text:
Pieces of Yesod: Inverting a Haskell Function
I've recently been working with web frameworks, and decided to have a play with what Haskell has to offer for web resources. One of the several frameworks available is Yesod. Web frameworks need some sort of mapping between URLs and internal logic, usually called routing. In Yesod, routing is done with a "pieces" mechanism. You might declare in your routes:
/resources/#SortBy ResourcesR GET
And this will mean that if you access example.com/resources/d, that will translate into a call that turns the string "d" into a value of type SortBy, which is then passed to getResourcesR. It also means that if you use the syntax "@{ResourceR Date}" in your template files, this will be translated into example.com/resources/d. This translation is done is with the "pieces" classes, for example the single piece class:
class SinglePiece a where fromSinglePiece :: Text -> Maybe a toSinglePiece :: a -> Text
So a value should always be translatable into a part of a URL (i.e. Text), and an arbitrary URL part may be a valid value. Here's a simple sorting-order type:
data SortBy = Date | Popularity | Title
And here's the trivial SinglePiece instance:
instance SinglePiece SortBy where fromSinglePiece "d" = Just Date fromSinglePiece "p" = Just Popularity fromSinglePiece "t" = Just Title fromSinglePiece _ = Nothing toSinglePiece Date = "d" toSinglePiece Popularity = "p" toSinglePiece Title = "t"
There's several drawbacks with this code. The major drawback is obvious: the code is repetitive! It expresses the same simple mapping from sort order to text twice, once in each direction. This is tedious. Another drawback is that is a potential source of bugs if I make a typo. SinglePiece does have an obvious property for testing: fromSinglePiece . toSinglePiece == Just. I also need to make sure I cover all the possible sorting values. The nice thing about toSinglePiece (rather than using a lookup table) is that if I use the GHC flags -fwarn-incomplete-patterns -Werror, it will warn me if I miss out a case. So if I add a new sort order, say Author, and forget to change toSinglePiece, I'll get a compile-time error as soon as I try to compile (which is quicker even than a test). But fromSinglePiece doesn't have the same advantage: if I forget a new case for Author, I'll only know about it because of my test.
The way to fix my problems is to stop repeating myself. I can change the code to this:
instance SinglePiece SortBy where fromSinglePiece = invert toSinglePiece toSinglePiece Date = "d" toSinglePiece Popularity = "p" toSinglePiece Title = "t"
That invert function looks a bit magical! Broadly, its type is:
invert :: (a -> b) -> (b -> Maybe a)
Now, as it stands, the invert function is not implementable; there's no way to arbitrarily invert a Haskell function. But we can brute force an inversion if we know the full range of inputs. That's possible with the help of some automatically derivable Haskell type-classes:
data SortBy = Date | Popularity | Title deriving (Eq, Enum, Bounded) invert :: (Enum a, Bounded a, Eq b) => (a -> b) -> (b -> Maybe a) invert f = flip lookup $ map (f &&& id) [minBound..maxBound]
We use Enum and Bounded to get the list of all possible inputs, then form a lookup table which we can reference to find the inverse of a value. So now we're able to write just toSinglePiece, and automatically derive fromSinglePiece. No repetition and less possible source of mistakes. The only problem is that invert might be a bit slow. Instinctively, it feels like the lookup table can't be as fast as Haskell's built-in case structure. To find out, let's whip up a test using the Criterion benchmarking library.
I'm testing the performance of fromSinglePiece on the three valid URLs and one invalid, i.e.
main = defaultMain [bench "benchName" $ nf (map fromSinglePiece :: [Text] -> [Maybe SortBy]) ["d", "p", "t", "x"]]
I ran this once on the original fromSinglePiece that used a case statement (calling that "cases"), and once on the new fromSinglePiece that uses the lookup table (calling that "invert"), compiling with -O2 each time on GHC 7.0.3. Here's the results:
benchmarking cases collecting 100 samples, 23951 iterations each, in estimated 1.011024 s bootstrapping with 100000 resamples mean: 423.0417 ns, lb 421.8167 ns, ub 426.2270 ns, ci 0.950 std dev: 9.136906 ns, lb 1.879618 ns, ub 16.88352 ns, ci 0.950 found 2 outliers among 100 samples (2.0%) 2 (2.0%) high severe variance introduced by outliers: 0.997% variance is unaffected by outliers benchmarking invert collecting 100 samples, 21664 iterations each, in estimated 1.011000 s bootstrapping with 100000 resamples mean: 466.8043 ns, lb 466.7298 ns, ub 466.9089 ns, ci 0.950 std dev: 448.0250 ps, lb 340.4309 ps, ub 723.9564 ps, ci 0.950 found 2 outliers among 100 samples (2.0%) 1 (1.0%) high severe variance introduced by outliers: 0.990% variance is unaffected by outliers
So the difference in speed is only around 10%. I can accept that cost in order to not repeat myself everywhere. Obviously, many types used with SinglePiece are not a trivial conversion between a type constructor and a text value, but for those that are, I found this trick useful.
Testing a Side-Effecting Haskell Monad
In this post I'm going to continue discussing testing CHP, this time focusing on the CHP monad. The monad is a bit complex (and indeed, there is a subtle bug in the current version of CHP to do with poison-handling) because it has several semantic aspects:
- it is an error-handling/short-circuiting monad (because it must obey the poison semantics),
- it has some extra semantics to do with choice that treats the leading action differently,
- underneath it all, there is the IO monad, which must be lifted correctly.
CHP is a monad with side-effects: quite aside from the communication with parallel processes, the presence of lifted IO means that it can have arbitrary side-effects. This means, if my terminology is correct, that we need a check for operational equality rather than denotational. Let's explore this by considering testing an error-handling monad.
Testing An Error-Handling Monad
The Either type can be used as an error-handling monad by using the Left constructor to hold an error, and the Right constructor to hold a successful return. One property that should hold is that Left e >>= k == Left e. That's an actual Haskell equality; we can test that property for any function k, and use actual equality on the result.
It's also possible to use a similar error-handling monad transformer. The transformers library offers an ErrorT e m a type that allows you to wrap a monad "m", using error type "e", with successful returns of type "a" (with a function throwError :: e -> ErrorT e m a for introducing errors). We can test this using the Identity monad as type "m", which would make sure the code was pure. But the semantics of this error transformer involve what actions occur in the error monad. For example, runErrorT (m >> throwError e >> n) should be equivalent to m >> return (Left e), but usually m (which is a monadic action) cannot be directly compared for equality.
Setting this in the IO monad makes it all much clearer: runErrorT (lift (putStrLn "Hello") >> throwError e >> lift (putStrLn "Goodbye")) should print Hello on the screen, and then finish with an error — and not print Goodbye. Testing this is difficult because we need to have a harness that can check for which side-effects occurred, making sure the right ones (e.g. printing Hello) did happen, and the wrong ones (e.g. printing Goodbye) didn't happen.
This is exactly the situation that the CHP monad is in; we always have IO beneath the CHP monad (which we can't swap out for a more easily testable monad!), so we must test equality of code by checking which side effects occurred. We need to check that liftIO_CHP (putStrLn "Hello") >> throwPoison >> liftIO_CHP (putStrLn "Goodbye") prints Hello then throws poison, and doesn't print Goodbye. Printing text is a difficult side-effect to track in a test harness, but the nice thing about IO is that it has a whole host of side-effects to choose from! So I test by observing alterations to a Software Transactional Memory (STM) variable (TVar) — therefore my test inputs are of type TVar String -> CHP a.
Testing CHP's Error-Handling
I use these two functions as a harness to execute the CHP code:
runCHPEx :: CHP a -> IO (Either SomeException a) runCHPEx m = (Right <$> runCHP m) `C.catches` [Handler (\(e::UncaughtPoisonException) -> return $ Left $ toException e) ,Handler (\(e::ErrorCall) -> return $ Left $ toException e)] runCode :: (TVar String -> CHP a) -> IO (String, Either SomeException a) runCode m = do tv <- newTVarIO "" r <- runCHPEx (m tv) s <- atomically (readTVar tv) return (s, r)
The runCode function gives back (in the IO monad) the String that was the final value of the TVar, and the result of running the CHP computation — either an uncaught poison/error exception or an actual return value. (One planned change to CHP semantics in version 3.0.0 is that uncaught poison gets translated into an exception, rather than giving runCHP a Maybe-wrapped return.) Here's some example HUnit tests (with some useful helper functions):
obsTestPoison :: Test obsTestPoison = TestList [("ab", Right 'b') ==* \tv -> tv!'a' >> tv!'b' ,("", Left UncaughtPoisonException) ==* const throwPoison ,("a", Left UncaughtPoisonException) ==* \tv -> tv!'a' >> throwPoison ] where (!) :: TVar String -> Char -> CHP Char (!) tv c = c <$ (liftIO_CHP $ atomically $ readTVar tv >>= writeTVar tv . (++[c])) (==*) :: (String, Either UncaughtPoisonException Char) -> (TVar String -> CHP Char) -> Test (==*) x m = TestCase $ runCode m >>= assertEqual "" (onLeftSnd Just x) . onLeftSnd fromException where onLeftSnd :: (b -> c) -> (a, Either b d) -> (a, Either c d) onLeftSnd f (x, Left y) = (x, Left $ f y) onLeftSnd f (x, Right y) = (x, Right y)
The left-hand side of the starred equality is the expected result. The right-hand side is the code (which is of type TVar String -> CHP Char) which should produce that result.
So by observing deliberately-placed side-effects in the code, we can check for equality in a side-effecting monad. These unit tests aren't the only way I'm testing my monad though — in my next post, I'll build on this to form a more advanced property-based testing technique.
Testing a Haskell Library
I'm currently gearing up for a CHP-3.0.0 release. Version 3 will be (internally) simpler in some places, faster in others, and has a slightly simplified API. The content of the library is mostly there — but I'm not yet ready to release because I want to write more documentation, and more tests.
Testing concurrent programs is notoriously tricky — the exact sequence of actions is non-deterministic, and sometimes bugs only occur when actions end up occurring at specific times. There's various aspects of CHP that particularly warrant testing:
- The central event-synchronisation mechanism (which underlies channels, barriers, choice and conjunction).
- The surrounding communication mechanisms (i.e. the exchange of data) for channels.
- The monad, poison, and all the associated semantics.
- Support for tracing.
- Wiring combinators (especially the four-way and eight-way grid wiring).
In this post, I'll talk about the first item: testing the central event-synchronisation mechanism. This is absolutely crucial to the correct functioning of CHP — if there's a problem in this algorithm, it will affect any code that uses CHP. The algorithm itself is effectively a search algorithm, which looks for events that can take place. The input to the search algorithm is scattered across several Software Transactional Memory (STM) TVars (Transactional Variables) thoughout the system, and the search takes place in a single transaction.
Testing STM-Based Algorithms
The really nice thing about testing an STM-based search algorithm is that we don't actually have to worry about the concurrent aspects at all. An STM transaction is guaranteed to be free of interference from other transactions. In our test harness, we set up all the TVars to our liking, run the search transaction and look at the results — and this is a perfectly suitable test, even if the real system will have several competing transactions running at different times.
The Search Algorithm to be Tested
Our search algorithm looks at all of the processes and finds which events (if any) can currently synchronise. Each process makes a set of offers (or offer-set) — essentially saying that it wants to complete one of the offers. Each offer is a conjunction of events that need to be completed together. An event can complete if, and only if, the number of processes making an offer on it is equal to the event's enroll count, and all the appropriate offers can complete. Time for an example! Let's say we have processes p, q, and r which have the code:
p = readChannel c <&> readChannel d q = writeChannel c 0 r = writeChannel d 0 <|> (syncBarrier a <&> syncBarrier b)
Barrier "a" has an enrollment count of 1, barrier "b" has an enrollment count of 3, and the channels are all one-to-one, so they have a fixed enrollment count of 2. We say that p has an offer-set with two offers: one offer contains just "c", the other offer contains just "d". Process q has an offer-set with one offer, which contains just "c". Process "r" has an offer-set with two offers: one contains just "d" and the other contains "a" and "b". The answers to the search algorithm in this situation is that p and q can communicate together on channel c, or p and r can communicate on channel d.
Writing Individual Test Cases
So we have an example, but now we need to code that up. This involves creating events for a, b, c and d, setting their enrollment counts, recording all the offer-sets — and then running the search that we actually want to test. If we had to spell that out long-hand for every test, we would soon be bored stiff. So of course we make some helper functions to allow us to specify the test as simply and clearly as possible — in effect, we can create a testing EDSL (Embedded Domain Specific Language). Here's my code that's equivalent to testing our previous example:
testD "Blog example" $ do [a,b,c,d] <- mapM evt [1,3,2,2] p <- offer [c, d] q <- offer [c] r <- offer [d, a&b] return $ (p ~> 0 & q ~> 0) `or` (p ~> 1 & r ~> 0)
The first line in the do-block creates our events with associated counts. The next lines make all the offers that we discussed. Note that the distinction between channels and barriers has vanished — that was useful for relating the example to actual CHP code, but underneath this, both channels and barriers use the event mechanism, which is what we're actually testing here. The final line declares the possible results: either p will choose item 0 in its list of offers (that's "c") and q will choose item 0 (also "c"), or p will choose item 1 and r will choose item 0 (both "b").
The nice thing here is that the test is easy to read, and corresponds very closely to what I wanted to express. Writing lots more tests is easy — which encourages me to do so, and thus my function ends up better tested. I've written about 25 of these tests, each aiming at testing different cases.
Implementation of my Testing EDSL
I'll show some of the details here of how I put together my testing EDSL. The monad it uses is just a wrapper around the state monad, building up a list of events, and offers on those events:
newtype EventDSL a = EventDSL (State ([EventInfo], [CProcess]) a) deriving (Monad) data EventInfo = EventInfo {eventEnrolled :: Int} deriving (Eq, Show) type CProcess = [CEvent] -- The list of conjoined events newtype CEvent = CEvent {cEvent :: [Int]}
Events and offers are represented simply by a wrapper around an integer (an index into the lists stored in our state) — we use newtypes to stop all the Ints getting confused with each other, and to stop accidental manipulation of them in the DSL. Our evt and offer functions are then trivial manipulations of the state:
evt :: Int -> EventDSL CEvent evt n = EventDSL $ do (evts, x) <- get put (evts ++ [EventInfo n], x) return $ CEvent [length evts] newtype COffer = COffer {cOffer :: Int} deriving (Eq) offer :: [CEvent] -> EventDSL COffer offer o = EventDSL $ do (x, ps) <- get put (x, ps ++ [o]) return $ COffer (length ps)
To allow use of the ampersand operator in two different places (the input and the result), we add a type-class:
class Andable c where (&) :: c -> c -> c instance Andable CEvent where (&) (CEvent a) (CEvent b) = CEvent (a ++ b)
For the expected result, we use this data type:
data Outcome = Many [[(Int, Int)]]
Each item in the list is a different possible outcome of the test (when there are multiple results to be found, we want to allow the algorithm to pick any of them, while still passing the test). Each outcome is a list of (process index, chosen-offer index) pairs. We have some combinators for building this up:
(~>) :: COffer -> Int -> Outcome (~>) (COffer p) i = Many [[(p, i)]] instance Andable Outcome where (&) (Many [a]) (Many [b]) = Many [a++b] or :: Outcome -> Outcome -> Outcome or (Many a) (Many b) = Many (a ++ b)
Ultimately our test has type EventDSL Outcome, and we run the inner state monad, we get back: (([EventInfo], [CProcess]), Outcome). This forms the input and expected result for the test, which we feed to our helper functions (which are too long and boring to be worth showing here), which use HUnit for running the tests.
Property-based Testing
Probably Haskell's most famous testing framework is QuickCheck (its cleverer cousin, Lazy Smallcheck, deserves to be just as well-known). This uses property-based testing: you specify a property and it generates random input, and checks that the property holds. This diagram is how I believe property-based testing is intended to work:
The size of the box is meant to indicate effort; the biggest bit of code is what you're testing, you may need some effort to generate random input data, and then you check that some simple properties hold on the output.
So let's think about some simple properties of our search algorithm. I can think of some:
- Any events that complete must have the same number of processes choosing them as the enroll count.
- Any events that don't have enough processes offering definitely can't complete.
- Processes can't select an offer index that's invalid (e.g. if p has 2 offers, it can't select offer 3).
All of these properties seem to be to be pussyfooting around the main property of the search algorithm that I want to test:
- The search algorithm finds a correct answer when one is available.
That certainly sounds simple. But how do we know what the possible correct answers to the search algorithm are? Well, we need to write a search algorithm! Often when I come to use QuickCheck, how it ends up working is this:
It feels a lot like double-entry validation; to calculate the expected result, I must code the same algorithm again! In this instance, I wrote a brute-force naive search that is checked against my optimised clever search. I'm not sure if this is still technically property-based testing, but QuickCheck is still handy here for generating the random input. (I guess a search algorithm is a bad choice for using property-based testing?) Regardless: I wrote my brute force search and tested my algorithm. It found no bugs, but now I have two sets of tests supporting me: one set of hand-crafted interesting tests, and a second version of the algorithm used with randomly generated input to pick up the cases I might have missed.
This post has been a bit light on technical detail, mainly because testing the algorithm involves a lot of dealing with the internals of my library that would take too long to explain here, and which would not be very interesting. My summary is this: constructing testing EDSLs makes your unit tests clearer to read and easier to write, which in turn encourages you to write more tests. I haven't found property-based testing as useful as unit tests, but if you have a simple dumb solution and you want to check your optimised clever solution maintains the same behaviour, QuickCheck (or Lazy SmallCheck) is a handy way to test equality of functions.
Parallel Composition in Haskell
CHP, my Haskell concurrency library, allows you to run processes in parallel. One way of doing so is this binary operator:
(<||>) :: CHP a -> CHP b -> CHP (a, b)
Informally, the behaviour is as follows: this starts both processes running (using Haskell's forkIO under the hood) and waits for them both to terminate and return their results. They can terminate at different times, but the parent process (the one running that composition) will wait for both to terminate before it returns. This parallel composition is not uncommon — for example, the parallel-io package provides a similar operation. In this post I'll talk about the properties we would expect from this composition, and how to make them hold in CHP — but this easily generalises to making them hold for a parallel composition operator in the IO monad (CHP being a thin layer on top of IO).
Properties of Parallel Composition
I intuitively expect that parallel composition should be commutative: p <||> q should be the same as q <||> p. I'd also expect associativity; this:
do (x, (y, z) <- p <||> (q <||> r)
should be equivalent to:
do ((x, y), z) <- (p <||> q) <||> r
Another property (which I'll call the unit law) is that composing something in parallel with a null (or more generally, a short-running) computation should have no effect, that is p should be equivalent to:
p <||> return ()
Finally, I'd expect independence; if I compose p in parallel with q, I would not expect p to behave any differently (or have its environment behave any differently) than if it was not part of a parallel composition. So there are our four properties: commutativity, associativity, the unit law and independence. Let's consider the behaviour of our parallel composition, to try to make sure it satisifes all of these.
Normal Execution
For those, like me, who like concrete code to look at, a basic implementation of parallel composition that works with normal execution (we'll add to it as we go along) is:
(<||>) :: CHP a -> CHP b -> CHP (a, b) (<||>) p q = liftIO_CHP $ do pv <- newEmptyMVar qv <- newEmptyMVar forkIO $ executeCHP p >>= putMVar pv forkIO $ executeCHP q >>= putMVar qv (,) <$> takeMVar pv <*> takeMVar qv
(We're using liftIO_CHP :: IO a -> CHP a and executeCHP :: CHP a -> IO a to go between the monads.)
If all the processes being composed execute and terminate successfully, all the properties easily hold. All the processes start up, they all run, and when they all complete we get the results back. If one of the processes doesn't terminate, the properties also all hold — the composition waits for them all to terminate, so if p doesn't terminate, the whole composition will not terminate, no matter which order the processes are in, or how we've associated the composition.
(This is the only CHP-specific aspect of our parallel composition.) CHP processes don't have to terminate successfully; they can also terminate with poison. The semantics with respect to poison are simple, and preserve all our properties; if either process terminates with poison, the composition will terminate with poison once both child processes have finished. We can update our implementation, based around the adjusted type of executeCHP that now indicates whether a process terminated with poison:
data WithPoison a = Poison | NoPoison a executeCHP :: CHP a -> IO (WithPoison a) (<||>) :: CHP a -> CHP b -> CHP (a, b) (<||>) p q = merge =<< liftIO_CHP (do pv <- newEmptyMVar qv <- newEmptyMVar forkIO $ executeCHP p >>= putMVar pv forkIO $ executeCHP q >>= putMVar qv (,) <$> takeMVar pv <*> takeMVar qv) where merge (NoPoison x, NoPoison y) = return (x, y) merge _ = throwPoison
This is very similar to our first definition, but it merges the values afterwards; they are only returned if neither side threw poison (otherwise poison is thrown). This again preserves all the properties, although associativity may require a little explanation. Consider p <||> (q <||> r). If p terminates with poison, the outer composition will wait for the inner composition to finish (which means waiting for q and r), then throw poison. If r terminates with poison, the inner composition will wait for q, then throw poison; the outer composition will wait for p to also finish, then throw poison. So the behaviour is the same no matter which part of the nested composition throws poison.
(Synchronous) Exceptions
The termination rules given for poison extend easily to exceptions (poison is really just a kind of exception anyway). If either process terminates with an exception (because it wasn't trapped, or it was rethrown), the parent process will rethrow that exception. If both processes throw an exception, an arbitrary one of the two is thrown by the parent process. We make exceptions "beat" poison: if one process throws an exception and the other exits with poison, the exception is rethrown and the poison is dropped. Our slightly adjusted implementation is now:
(<||>) :: CHP a -> CHP b -> CHP (a, b) (<||>) p q = merge =<< liftIO_CHP (do pv <- newEmptyMVar qv <- newEmptyMVar forkIO $ wrap p >>= putMVar pv forkIO $ wrap q >>= putMVar qv (,) <$> takeMVar pv <*> takeMVar qv) where wrap proc = (Right <$> executeCHP proc) `catch` (\(e :: SomeException) -> return (Left e)) merge (Left e, _) = throw e merge (_, Left e) = throw e merge (Right Poison, _) = throwPoison merge (_, Right Poison) = throwPoison merge (Right (NoPoison x), Right (NoPoison y)) = return (x, y)
The wrap function catches any untrapped exceptions from the process, and sends them back to the parent process instead of a result. The merge function prefers exceptions to poison, and only returns a result when neither side had an exception or poison.
(Another possibility for exceptions would have been ignoring the exceptions from the child processes; this would maintain commutativity, associativity and independence, but would have broken the unit law, because when p threw an exception, it would not be propagate if p was wrapped inside a dummy parallel composition.)
Asynchronous Exceptions
Asynchronous exceptions can be received by a thread at any time (unless you mask them), without that thread doing anything to cause them. CHP is a concurrency library with its own mechanisms for communicating between threads and terminating, so I don't usually use asynchronous exceptions in CHP programs. But that doesn't stop them existing, and even if you don't use them yourself (via killThread or throwTo) it doesn't stop them occurring; asynchronous exceptions include stack overflow and user interrupts (i.e. Ctrl-C). So we need to take account of them, and preferably do it in such a way that all our expected properties of parallel composition are preserved.
When we execute a nested parallel composition, such as p <||> (q <||> r), we actually have five threads running: one each for p, q, and r, one for the outer composition and one for the inner composition:
(Each circle is a thread.) We must assume, in the general case, that any one of these threads could potentially receive an asynchronous exception (e.g. the system can kill any thread it likes with an async exception, according to the docs).
Child Process Receives an Asynchronous Exception
Let's start by discussing what happens if a child process such as q gets an asynchronous exception directly. One possibility is that q may trap the exception and deal with it. In that case, we're fine — the parallel composition never sees the exception, and since it's been trapped by q, it shouldn't escape from q anyway. But q may not handle it (or may handle and rethrow, which is the same from the point of view of our operator). So what should happen when q terminates with this exception? One possibility would be to immediately kill its sibling (or throw the exception to them). This would completely break independence; r would now be vulnerable to being killed or receiving an asynchronous exception initially targeted at another process, just because it happens to be composed with q. The only way to preserve independence is to treat the asynchronous exception in a child process as we do synchronous exceptions; we wait for both processes to terminate, and then the parent exits by rethrowing that asynchronous exception. This preserves commutativity, associativity (no matter which of p, q and r get the exception, all will be allowed to finish, and then the outer composition will end up rethrowing it, potentially via the inner composition doing the same) and independence. Our unit law is preserved if p receives the exception (see the next section for more discussion on the unit law).
Parent Process Receives an Asynchronous Exception
Now we move on to consider what happens if the parent process in a composition receives an asynchronous exception. This is actually one of the most likely cases, because if your program consists of:
main = runCHP (p <||> q)
If the user hits Ctrl-C, it's the parent process that will get the exception, not p or q. We mustn't terminate only this thread and leave p and q dangling. The whole point of the parallel composition is that you scope the lifetime of the processes, and we don't want to break that. We could catch the exception, wait for p and q to terminate and then rethrow it. But if the exception is something like a user-interrupt then it seems wrong to ignore it while we wait for the oblivious child processes to terminate. So the semantics are this: when the parent process receives an asynchronous exception, it rethrows it to all the child processes. This trivially preserves commutativity. Independence is also satisfied; if the processes weren't in the parallel composition, they would receive the exception directly, so rethrowing it to them is the same effect as if they weren't composed together.
The unit law and associativity are in danger, though. Consider our unit law example: p <||> return (). If p does not trap the asynchronous exception that the parent throws to it, the unit law is preserved; p will get the exception, and then exit with it (regardless of the other side), which will cause the parent to exit with the same exception, so it is as if the composition was not there. If p does trap the exception, the behaviour becomes a race hazard with one of two behaviours (the difference is bolded):
- The parent receives the exception, and throws it to its children. The return () process has not yet terminated, this then terminates with an uncaught exception. p traps the exception and deals with it, but when the parallel composition exits, the exception is rethrown from the return () branch; this exception would not have been thrown if p was executing alone, because p would have caught it.
- The parent receives the exception, and throws it to its children. The return () process has already terminated succesfully. The exception is thus only thrown to p. p traps the exception and deals with it, so when the parallel composition exits, the exception is not visible, just as if p was executing alone.
There are two ways to "fix" this, by adjusting our unit law: one is to say that the unit law only holds if child processes do not trap exceptions. The other is to say that the unit of parallel composition is not return (), but rather:
return () `catch` (\(e :: SomeException) -> return ()
The problem with that is that catch is in the IO monad, and to be part of the parallel composition it needs to be in the CHP monad, which requires a lot of type-fiddling. I'm still thinking about this one for CHP, but if you were dealing with IO, changing the unit to the above would probably make most sense.
Associativity also has some caveats. Here's our diagram again, with the outer composition at the top, and the inner composition its right-hand child:
If the outer composition receives an exception, all is well; the exception is thrown to the children, which includes the inner composition — and the inner composition throws to its children, so all the processes get it. If any of them don't trap the exception, the exception will be the result of the whole composition no matter which way it was associated — and if all trap it, associativity is still preserved. However, if the inner composition receives an exception, associativity is not preserved; the inner composition will throw the exception to its children but the outer composition will not know about the exception immediately, so only the processes in the inner composition will see the exception. Now it matters which processes are in the inner composition and which is in the outer composition. But this seems morally fair: if an exception is thrown to an inner part of the whole composition, that already depends on the associativity, so it's unreasonable to expect that the composition can function the same regardless of associativity.
Masking Asynchronous Exceptions
When defining our parallel composition operator, we also need to be careful about precisely when asynchronous exceptions might occur. One major difference between poison and asynchronous exceptions is that poison can only occur when you try to use a channel or barrier, whereas asynchronous exceptions can occur any time. This is a plus and minus point for both sides; it means poison is easier to reason about, but asynchronous exceptions can interrupt processes which are not using channels or barriers (e.g. that are blocked on an external call). To make sure we don't receive an asynchronous exception at an awkward moment, such as inbetween forking off p and forking off q (which would really mess with our semantics!), we must mask against asynchronous exceptions, and only restore them inside the forked processes. You can read more about masking in the asynchronous exception docs. So, the final adjusted definition of parallel composition that I will give here is as follows (we don't need a restore call around takeMVar because the blocking nature implicitly unmasks exceptions):
(<||>) :: CHP a -> CHP b -> CHP (a, b) (<||>) p q = merge =<< liftIO_CHP (mask $ \restore -> do pv <- newEmptyMVar qv <- newEmptyMVar let wrap proc = restore (Right <$> executeCHP proc) `catch` (\(e :: SomeException) -> return (Left e)) pid <- forkIO $ wrap p >>= putMVar pv qid <- forkIO $ wrap q >>= putMVar qv let waitMVar v = takeMVar v `catch` (\(e :: SomeException) -> mapM_ (flip throwTo e) [pid, qid] >> waitMVar v) (,) <$> waitMVar pv <*> waitMVar qv) where merge (Left e, _) = throw e merge (_, Left e) = throw e merge (Right Poison, _) = throwPoison merge (_, Right Poison) = throwPoison merge (Right (NoPoison x), Right (NoPoison y)) = return (x, y)
(In fact, this isn't quite enough. I'm currently adding a finallyCHP function that acts like its IO equivalent, and to support that I must push the restore call inside executeCHP to avoid asynchronous exceptions being acknowledged before the finallyCHP call is executed, but that's a bit further into CHP's internals than I want to go in this post.)
Hopefully that was a useful tour of parallel composition semantics in Haskell. Synchronous exceptions are easily dealt with, but asynchronous exceptions (which were perhaps designed more for the forking model of thread creation than this style of parallel composition) make things a fair bit trickier.
Communicating Haskell Processes: The Long And The Short Of It
The Long
It's been a long time coming, but I have completed the final corrected version of my PhD thesis. It's entitled, rather unimaginatively (and against received wisdom), "Communicating Haskell Processes". (Communicating Haskell Processes, or CHP for short, is my concurrent message-passing library for Haskell.) A lot of what's in there has been on this blog before. The new bits are the slightly revised CHP design (which will be in the forthcoming 3.0.0 release) and operational semantics in chapter 3. It's freely available online for you to read, all 250+ pages.
The Short
Meanwhile, I've also put together a condensed version of the new material — including mobile (suspendable) processes, and automatic poison, neither of which I've written about anywhere else — into a paper for the Haskell symposium, which is a more palatable 12 pages. I'm not going to copy out the whole paper into this post, but here's a quick summary of automatic poison.
Poison is a way to shut down a process network: processes should catch poison (which can occur if a channel you are using becomes poisoned) and poison all their own channels, spreading the poison throughout the network until all of the processes have shut down. The standard idiom is to surround your whole code with an onPoisonRethrow block that poisons the channels:
deltaOrig :: Chanin a -> [Chanout a] -> CHP () deltaOrig input outputs = (forever $ do x <- readChannel input parallel_ [writeChannel c x | c <- outputs] ) `onPoisonRethrow` (poison input >> mapM_ poison outputs)
Automatic poison puts all this poison handling into an autoPoison function that wraps your process with the poison handling, so for the above we can substitute this instead:
deltaAuto, deltaAuto' :: Chanin a -> [Chanout a] -> CHP () deltaAuto = autoPoison deltaAuto' deltaAuto' input outputs = forever $ do x <- readChannel input parallel_ [writeChannel c x | c <- outputs]
I haven't saved masses of code there, but I think the latter version is more readable. Read the paper for more details.
Comments are welcome on the paper, which is due on Monday (6th June). Comments are slightly less welcome on the thesis, because it's already been sent for binding! If there is a mistake, I'm happy to correct it in the online version.
Programming Language Fiction
The latest issue of The Monad Reader (an electronic magazine vaguely themed around Haskell) was released this week — but rather than featuring technical articles, it's a special "poetry and fiction" edition. I decided to have a go at contributing, so I wrote a story about programming languages: in particular, what's important in a programming language. It's explored indirectly, via a discussion of one of my other interests: films. If you're interested, take a look. I'm open to feedback on my contribution, and I imagine Brent (the editor) is also interested as to whether the special edition was a worthwhile experiment.
I spent some time late last year working further on what I originally called behaviours. It grew much longer than a blog post, so it's ended up in the Monad.Reader electronic magazine, in the just-published Issue 17. Thanks are due to Brent Yorgey for his careful proof-reading and editing of the article. The accompanying code is already up on Hackage as the interleave package for those who want to play.
This week I'm also starting to prepare some slides; in two weeks' time I will be presenting at PADL 2011 in Texas. That's a talk that's on the automated wiring that I've covered on the blog before. Once that trip is out of the way, I'm hoping to have a bit more time for Haskell coding again.


text:
Councilwoman Letitia James won the Democratic public advocate runoff on Tuesday, becoming the party's nominee and all but assuring she will become the city's elected watchdog, and the first black woman to hold citywide office.
James defeated state Sen. Daniel Squadron in incomplete and unofficial returns and faces a general election next month without a Republican opponent.
James and Squadron were the top two finishers in the Sept. 10 primary, but neither eclipsed the 40 percent threshold that would have avoided the costly runoff. The winners of the higher-profile mayoral and comptroller primary contests stayed above that mark, meaning the race to fill the little-understood public advocate position was the only one on the ballot.
"Over the weeks and months this has been an intense journey but one worth taking," James said in her victory speech. "There's so much more work to do because the next generation of New Yorkers are at risk of losing the opportunities that allowed us to make it in this city."
The public advocate position has little real power and an annual budget of just $2.1 million, a small fraction of the $13 million it cost the city to hold the runoff, which was required by law.
But the post has become a springboard to higher office. The current public advocate, Bill de Blasio, is the Democratic nominee for mayor. He did not endorse anyone in the runoff.
De Blasio was one of many public officials who called for reforms to the costly runoff system.
James and Squadron have similar liberal positions on most issues, from the need for school reform to the creation of more affordable housing.
In a statement, Squadron said, "We ran this campaign making the case that the Public Advocate's office can be essential to our city — getting results for New Yorkers who need them. For New Yorkers without a voice, without high-powered lobbyists, without City Hall on speed dial. For people with no place else to turn. Their families need a strong Public Advocate. And I know that Tish will be their great advocate for New Yorkers across the city."
If elected in November, James would rank second only to the mayor, according to the city charter, and would be in a position to badger the administration.
James, a three-term councilwoman from Brooklyn, had the support of most unions.
Squadron, who represents parts of Brooklyn and Manhattan, had utilized a larger campaign account and had the backing of the city's major newspaper editorial boards and many high-profile politicians, including his former boss U.S. Sen. Charles Schumer.

subset: commoncrawl


text:
Updated Website from Abrasive-Waterjet Manufacturer
There are 0 comments | Post a comment
Saturday, October 1, 2011
Omax Corp., Kent, WA, has launched a new corporate website to promote its abrasive-waterjet cutting systems and accessories. Visit the site, www.omax.com, to review new-technology introductions and feature articles, follow links to Omax social-media pages, view a calendar of events and participate in a message board.
See also: Omax Corporation
Related Enterprise Zones: Fabrication
Reader Comments
There are no comments posted at this time.


text:
FUL Aid Drops 10ml
By Mankind Pharma Pvt Ltd
By Mankind Pharma Pvt Ltd
M.R.P.: Rs.12.30
(per unit)Check out cheaper substitutes
Need Help? 72007-12345
Please enter your name, mobile number and E-mail ID, and we will send you an email when the requested item is back in stock.
Copyright © 2019 Netmeds Marketplace Limited.
All rights Reserved


text:
Opinion: California's Rookie Republican
Editorial page writer Allysia Finley on why gubernatorial challenger Neel Kashkari should sharpen his message. Photo: Associated Press
This transcript has been automatically generated and may not be 100% accurate.
... I ... I ... the opinion Journal why Mary Kissel ... how the user to the polls later this year and elect a governor ... of the stick with the Democrat incumbent Jerry Brown ... to go for the Republican challenger House race going ... I've got editorial writer Elisa Finlay joining me now ... Sully said the GOP challenger due to scarring ... I always feel like a football experience is the guy ... okay so this ... is the son of man middle-class union in France Switzerland seem to get in ... a nice background their narrative ... however he has some personal baggage that soon ... that could hurt in an election namely he helps run the seven hundred billion dollar bailout for ... well We is inventory page one start using it would be in a negative for him is he is in it's it's ... it's the it's ... bailouts Democrats a today is ... I don't see how this and play out well for okay so that's initiating S tequila ... a quote ... from him and he said ... well now we're sporting a life of privilege like Jerry Brown said Governor ... Jerry Brown is a million dollars injected the bought stock ... I needed Jack in the box ok unleash ... so we'll just RUC is the writing is that ... class warfare populist ... policies that are extremely defensive and that's how he's on the defense about his own wealth the union summary gone after him for his wealth and a knack for having worked at Goldman Sachs that means my time to neutralize the issue ... that he was really stunning The or a penny here ... I mean people don't book a Jerry route was actually incredibly known to be very austere unfurl on his personal life ... aam as long as you know me in how he actually wants the government ... I need ... when you look at him as being ... frugally should in this sense that the Mayans Sea Needleman Robin one of ... the story is also highlight its use of the economic struggles ... of California ... state does have a pre high unemployment rates mother problems ... is that the helping win in the run-up to November ... I think the problem is that that that things generally are improving in this state J Bratton sixty percent approval rating he a real state is up by about twenty per cent over the year and that's and that's with the tour and these people's ... spirits and you know was so fun about is booming unemployment rate is dropping so people just don't see you ... the problem is as big as its new Chinese consumption is right off the skin CME does he'll pitch Faria keyhole I think I'm going into this would be ... it's moved uphill climb in the eighties chances were pretty slim shady run for governor of the Shoshone of romper ... he's got a very big says I aam people who run for cover ... usually are ... but he probably would've stood a better chance if he ever for Comptroller said Berkshire Estreicher okay well we're going to keep a very close eye on the race as reregulation Finlay thank so much ... for the state ...


text:
In today's industrial landscape, automation is an essential component in production and manufacturing, ensuring your company's competitive edge. Your overall efficiency depends on the safe and reliable functioning of your automation equipment.
Our services enable you to ascertain the quality, general as well as functional safety (FS) of your automation systems and to make any necessary adjustments or improvements, whether required by law or simply to boost productivity. Additionally, we offer the only worldwide extended vocational training program in functional safety where knowledge and competencies are approved by a neutral third party. Our trainers have in-depth knowledge and broad experience. With a solid background and extensive experience in the field of automation technology, our experts around the globe are prepared to assist you.
Unlock your international success with our Market Access Services. To ensure a smooth and fast market access, we support you with all necessary certifications, inspections and regulatory researches.


text:
Not on FilmNet yet?
|Join now to follow the work of countless high quality filmmakers or market your films with our unique tools:
|Find exactly the films and music videos you want, and watch content in high quality.
|Read professional film reviews and contribute your own reviews.
|Communicate with filmmakers and other viewers.
|Browse a comprehensive database of independent films, people and companies.
©2008-2009 Joakim Nygård & Andreas Pankratz
The project is hosted at http://zfdebug.googlecode.com and released under the BSD License
Includes images from the Silk Icon set by Mark James


text:
Police have caught missing sex offender David Taylor in the Burnley area.
David was arrested earlier today (30 November) and will be returned to prison.
David Taylor, 26, of Lindsay Street, Burnley, had been recalled to prison in connection with allegations of assault.
Taylor had previously been convicted of raping a female under 15.


text:
- Did you mean
- classes events name free geauga county
Search results
CD Wire- December 2, 2019
hours" for less formal question/answer sessions. Note: These trainings are intended for county ... and more extreme rain events due to climate change pose current and future challenges for cities. ... created a phony email address in the name of sender to trick Ohio State employees into thinking the ...
Eaves Make Up Classes
219 Jenna Eaves Monday, December 2, 2019- 4:30pm to 8:00pm ...
CD Wire- November 18, 2019
support our CD colleagues, whose presentations were accepted: Name Date and Time Title Type Brooke Beam ... (learn.extension.org) to view and register for upcoming webinar sessions. Please share these events with others who may ... also be interested. Topics covered: Health Benefits of City Trees: Research Evidence & Economic ...
Farm Bill Update: Agricultural Risk Coverage (ARC)/Price Loss Coverage (PLC)
make informed program decisions. Flyer Location: OSU Extension Greene County, 100 Fairground Road, ...
Meet Mecah Mochoge: Aspiring to Help Fellow Veterans
To many, the story of a college student who started classes in the autumn of 2009 but is now ...
Farm Bill Update Program- Dec. 20
OSU Extension Greene County, 100 Fairground Road, Xenia Cost: Free Contact information: Trevor Corboy, ...
CD Wire- November 4, 2019
Smith at 202-223-7800, IEDC membership associate. Provide your contact info (name, title, etc.) and ... Bureau 4-H Center. Register here before November 12. GIS Day- November 13: GIS Day is an annual event ... Relations class are assisting the Dean's office with a project regarding State of the College and our ...
Three New Community Development Fact Sheets Published on Ohioline
Extension-Noble County, and Godwin Apaliyah, educator, CD, OSU Extension-Fayette County, co-wrote " Rural ... educator, CD, OSU Extension-Guernsey County, and Gwynn Stewart revised " Rural Neighbors—Living and ... Local Government." The fact sheet addresses how counties and cities can use port authorities as ...
CD Wire- October 21, 2019
Exhibit Area), 1680 Madison Avenue, Wooster, OH 44691 Monday, November 25 – Montgomery County Agricultural ... expand perspectives, build relationships and foster a culture of inclusion. The event is on November ... Schlegel (email@example.com) containing the following: Cover Page: Include Name, Faculty Rank, ...
Sewing Workshop Series- Easy Wallet
The 4-H Greene County Food and Fashion Board is offering a Learn to Sew Workshop Series. These ... workshops will take place once a month staring in September and running through December. Each class will ... Snowman All supplies will be provided All workshops will be held at the Greene County Extension office ...


text:
Working with AIX scalable volume groups - Part 2 - converting to scalable.
cggibbo 270000TMUJ Visits (47983)
Following on from my previous post, on working with scalable VGs. https://www.ibm.com/developerworks/mydeveloperworks/blogs/cgaix/entry/working_with_aix_scalable_volume_groups1?lang=en You may find yourself in a situation where you'd like to convert a VG to scalable. For example, you might start off with a normal VG i.e. one that can support a maximum of 256 LVs and 32 PVs. # mkvg -s 512M -y myvg hdisk5 myvg # lsvg myvg VOLUME GROUP: myvg VG IDENTIFIER: 00f6027300004c0000000133aa24d1f6 VG STATE:... [More]
Working with AIX scalable volume groups.
cggibbo 270000TMUJ Comments (4) Visits (58212)
Scalable volume groups first appeared in AIX 5.3. They allow a maximum of 1024 physical volumes and 4096 logical volumes per volume group. This is pretty cool for large systems. In the 'old days' we could end up in situations where we'd reached the maximum PV count (32 or 128) for a VG and have to create a new VG to work around the issue. I use scalable VGs for all my new large AIX system builds. The following command will create a scalable VG (named svg ) on hdisk4. You'll notice that MAX PVs is set to 1024 and MAX LVs is set to 256.... [More]


text:
PhoneDog's innovative comparison tool can help you save on cell phones and plans. Find the best phone and plan for you today with PhoneDog!
Confirmed by Samsung April 2014, the Galaxy Tab4 is coming to us with 1280x800 pixels, a 1.2GHz quad-core processor,...
Beau Hamilton
1 week 6 days ago
2 weeks 20 hours ago
Alex Wagner
3 weeks 2 days ago
3 weeks 4 days ago
More Featured Articles
Samsung Galaxy S8
Samsung Galaxy S8 written by Fiona Hutton
reviewed by Fee
Google Pixel 2
Google Pixel 2 vs. Horseshoe Lake
reviewed by Kjane79
Luna 5.5 4g LTE
reviewed by LSimko52
More Reviews
More Videos


text:
Lido Theatre
1763 Amsterdam Avenue,
New York,
1 person favorited this theater
The Bluebird Theatre opened in 1921 with seating for 600. By 1930 it had been re-named Ramona Theatre. On May 27, 1938, the facility's name was changed to Teatro Granada and it instituted a program of second run Spanish language films. After another name change, the Lido Theatre was sold to Dr. Alvin A. Childs in 1951.
Rechristened as the Faith Temple Church of God in Christ, Dr. Childs' Pentecostal church hosted the funeral service of Malcolm X on February 27, 1965. In 1974, the house of worship was yet again renamed, this time as the Childs Memorial Temple, and today it continues to serve the Sugar Hill community.
Recent comments (view all 5 comments)
It was still listed as the Bluebird Theatre in the 1926 edition of Film Daily yearbook, but by the 1930 edition of F.D.Y. it is listed as the Ramona Theatre.
The 1993 NYCLPC Landmark Designation Report for the Jaffe Theatre (now City Cinemas Village East) listed the Bluebird Theatre among the other Manhattan works of architect Harrison G. Wiseman.
Still remembered for holding the funeral service of Malcolm X in 1965, the Childs Memorial Church of God in Christ is being prepared for demolition, according to recent news reports. The ground site will be used for a 10-story apartment building on the north end, and a new and much larger church on the south end.
Iris theater?
in the 1940 tax photo
Interesting find, IATSE311! The titles on the marquee ("Con Las Alas Rotas" and "Tango Bar") are from Argentina.
Just login to your account and subscribe to this theater


text:
Wozniacki Wins Second Title in 2012 with VCORE Xi
- Date
- 22 October 2012
With the season at a close, YONEX players captured titles once again, finishing their season with glory. Last week in Moscow, Caroline Wozniacki (VCORE Xi 100) and Maria Kirilenko (EZONE Xi 98, PTGP125) competed at the Kremlin Cup.
No. 3 seed Caroline advanced to the singles final and faced No. 1 seed Samantha Stosur. Throughout the match, Caroline played strong, especially in her return games. She won 8 of 12 break points to defeat her opponent by 6-2, 4-6, 7-5. It was Caroline's first title since she started using the VCORE Xi 100, and her 20th WTA title. Playing with her VCORE Xi racquet, Caroline aims to finish this season as the top 10.
In the doubles final, No. 2 seed Maria and Nadia Petrova played against No.1 seed Ekaterina Makarova and Elena Vesnina. Maria recovered from an injury, resuming her tour in good condition, and was the runner-up in the doubles tournament.
The BGL BNP Paribas Luxembourg Open was also held last week, with No. 1 seeds Andrea Hlavackova (RQiS 2 Tour, PTGP125) and Lucie Hradecka winning the doubles title. In the final, they defeated No. 2 seeds Irina-Camelia Begu and Monica Niculescu in straight sets by 6-3, 6-4. The Czech doubles experts displayed their experienced performances, the same as they do in other tournaments.
Tournament Results
Kremlin Cup [Women's Singles - Final]
[3]Caroline Wozniacki (VCORE Xi 100)(DEN) def. [1]Samantha Stosur (AUS) 6-2 4-6 7-5
Kremlin Cup [Women's Doubles - Final]
[1]Ekaterina Makarova (RUS) / Elena Vesnina (RUS) def. [2]Maria Kirilenko (EZONE Xi 98, PTGP125)(RUS) / Nadia Petrova (RUS) 6-3 1-6 [10-8]
BGL BNP Paribas Luxembourg Open [Women's Doubles - Final]
[1]Andrea Hlavackova (RQiS 2 Tour, PTGP125)(CZE) / Lucie Hradecka (CZE) def. [2]Irina-Camelia Begu (ROU) / Monica Niculescu (ROU) 6-3 6-4
*Caroline's image is Toray PPO 2012, Andrea's image is US Open 2012.


text:
Concorde (Sun Xtender)'s PVX-12150HT AGM Battery
The PVX-12150HT battery has a copper alloy threaded insert terminal and is supplied with silicon bronze bolts, nuts, and washers for the required installation. This battery has a M8 terminal which has a torque value of 70 in-lb. After 15 cycles rated capacity is stated to be 77°F to 1.75 volts per cell. Product includes a 1-year warranty!
Features & Attributes
- Dimensions (LxWxH): 11.04 × 10.98 × 15.55 inches
- Weight: 124 lbs
- Copper Alloy Terminals for improved electrical connections.
- No exposed lead terminals. This change was incorporated to improve environmental safety and health.
- Threaded insert terminals are recessed to prevent short circuits across battery connections.
- New cover is flat top design. No protruding or exposed vent valves.
- Built in lifting handles, except PVX-490T, PVX-560T, and PVX-2240L.
- Reinforced container walls to reduce bulging.
- High Impact Strength Copolymer Polypropylene Case and Cover.
- Completely Sealed Valve Regulated Construction.
- Immobilized Electrolyte Non-Spillable.
- Maintenance Free Design Never Requires Watering.
- Absorbed Glass Mat (AGM) Micro-porous Glass Separators retain electrolyte.
- Flame Arresting Pressure Regulated Safety Valves.
- UL Recognized Systems Component.
- Positive Plates - Proprietary Lead Calcium Alloy - Negative Plates - Lead Calcium.
- Low Self Discharge Rate Approximately 1% per month at 25 C (77 F).
- Operates over a Wide Range of Temperatures from -40 C (-40 F) to +72 C (+160 F).
- Classified as "Non-Spillable Battery" for Transport.
- Most Part Numbers comply with DOT HMR49, Non-Hazardous Materials.


text:
(2) Agricultural labor In the case of agricultural labor, the term "employer" means, with respect to any calendar year, any person who— (A) during any calendar quarter in the calendar year or the preceding calendar year paid wages of $20,000 or more for agricultural labor, or (B) on each of some 20 days during the calendar year or during the preceding calendar year, each day being in a different calendar week, employed at least 10 individuals in employment in agricultural labor for some portion of the day.
26 USC § 3306(a)(2)
Scoping language
None identified. Default scope is assumed to be the entire title.
Is this correct?


text:
Outpatient services are
medical procedures or tests that can be done in a medical center without an
overnight stay. Many procedures and tests can be done in a few hours.
Outpatient services include:
Outpatient services usually cost less, because you don't need to stay
overnight. Staff members at outpatient centers are well trained in the service
they provide. Most of the time, these centers specialize in one kind of
treatment or procedure. Often all the care you need can be provided in one
Most people can choose an
outpatient center instead of a hospital if the needed service is available. But
not all medical procedures can or should be done at an outpatient
Your doctor may
recommend a center. You can also ask family or friends who have used outpatient
services to tell you about their experiences.
To find the right
center to provide the service you need, you'll need to ask some questions, such
Try to find out all you can about the outpatient
center before you use it. It's a good idea to visit the center before you
Many health and government agencies rate or report on the
quality of outpatient centers. Check with your state's board of medicine or
with your insurance company to learn more.
You can also use the
Quality Check website from the Joint Commission. For more information, go to
Frequently Asked Questions
Learning about outpatient services:
Using outpatient services:
Finding an outpatient service center:
More and more medical
procedures are being offered in qualified
outpatient service centers.
services are offered in many settings. For instance, medical schools often
provide various types of outpatient services, such as pain clinics or
rehabilitation centers. Other types of outpatient facilities include:
Many outpatient service centers specialize in a specific
area of medicine, such as orthopedics (bones) or cardiology (heart). These
centers, like many hospitals, have advanced equipment and highly trained
There are many benefits
outpatient services, depending on the type of medical
procedure you need and on what you prefer.
When choosing an outpatient facility, consider:
outpatient service centers are accredited and approved
for the types of treatment offered. But not all centers provide care that is right
for you. Be sure to find out whether the provider you're considering
is reputable and qualified. The following government and health agencies can
help you learn about the quality of outpatient service centers:
It is important to check
with your HMO, PPO, or health insurance provider to determine what outpatient services are covered. Your particular
health plan coverage may limit your choice of services.
a quality outpatient center before you have a medical procedure is the best way
to make sure that you'll receive excellent care. Friends and family who have
used outpatient services may tell you about their personal experiences. Often
your doctor will know about the quality of outpatient services in your area.
You may want to start your search by talking with your doctor about your options.
Next, find out which outpatient services are covered by your insurance company.
The following questions may help you find the outpatient service center that
best fits your needs:
You may have more questions based on your own health
issues and the type of procedure or test you need. Ask questions, listen
to the recommendation of your doctor and those you trust, and visit the
facility to get the information you need to make the best decision for
your health care.
This Joint Commission website has information about choosing a health care provider, patient safety, Quality Check (a way to check the performance of health care centers), and more.
The Joint Commission compiles reports and national information on various health care services, including outpatient service centers. If you want to check on the performance of an outpatient service center, use the Quality Check feature on this Web site.
The Agency for Healthcare Research and Quality (AHRQ) is
one agency within the U.S. Department of Health and Human Services. AHRQ
supports research initiatives that seek to improve the quality of health care
in America. AHRQ's mission is to improve the quality, safety, efficiency,
effectiveness, and cost-effectiveness of health care for all Americans. The website provides evidence-based information to help people make decisions about
health care services.
Other Works ConsultedFrey R (2009). Ambulatory surgery centers. In B Narins, ed., Gale Encyclopedia of Surgery and Medical Tests: A Guide for Patients and Caregivers, 2nd ed., vol. 1, pp. 42–45. Farmington Hills, MI: Gale.Gross RJ (2007). Preoperative planning for ambulatory patients. In NH Fiebach et al., eds., Principles of Ambulatory Medicine. 7th ed., pp. 1605–1633. Philadelphia: Lippincott Williams and Wilkins.Rastegar DA (2007). Practicing evidence-based medicine. In NH Fiebach et al., eds., Principles of Ambulatory Medicine, 7th ed., pp. 13–25. Philadelphia: Lippincott Williams and Wilkins.
Next Section:
Previous Section:
Last Revised:
October 27, 2011
Healthwise Staff
Medical Review:
Anne C. Poinier, MD - Internal Medicine & Michel M. Murr, MD - General Surgery, Bariatric Surgery
This information does not replace the advice of a doctor. Healthwise, Incorporated disclaims any warranty or liability for your use of this information. Your use of this information means that you agree to the Terms of Use. How this information was developed to help you make better health decisions.
To learn more visit Healthwise.org
© 1995-2012 Healthwise, Incorporated. Healthwise, Healthwise for every health decision, and the Healthwise logo are trademarks of Healthwise, Incorporated.


text:
An aging in place scenario, creates housing and health care options to provide support as defined by an individualís wishes and efforts to live independently. Aging in place can work best when it is employed as a part of a comprehensive plan for retirement and aging. A key step in implementing aging in place is to make your home aging friendly. As we age we don't hear so well, we sometimes forget or get confused and we can even outlive doctor's predictions about our longevity. So as long as we persist in growing older, why not arrange our homes to accommodate our reality. Incorporate memory triggers into the way we arrange cabinets and counters, add soft fabrics to muffle background noises, change appliances to better accommodate our short-comings.
Here is a book to help you make your homes senior-friendly.
Also visit: the Universal Design Living Laboratory:A National Demonstration Home at http://www.UDLL.com by Rosemarie Rossetti, PhD
If you want to learn more visit our Aging in place section .
Once you have an idea of the changes needed in the home, it is time to discuss the changes with a contractor/builder in your area. Below is a list of of such providers in your area.
Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /home/seniorresource/public_html/sraip6.php:314 Stack trace: #0 {main} thrown in /home/seniorresource/public_html/sraip6.php on line 314


text:
|Hi! I'm taking a little break and it might take me a few days to reply to comments and emails. I'll be back soon! :)
Wednesday, October 24, 2012
Cauliflower Cheeze and Peanut Butter Squares
It's Mandee's Cauliflower Cheeze! I've blogged about this one before, and have made it SO many times since that day! This beauty makes it to my belly at least every couple of weeks, sometimes once a week, and sometimes even twice a week. It's easy to make, it's delicious, and it's healthful. Triple WIN! Because I have made it so many times, I have made several variations of this dish: half cauliflower and half broccoli, half cauliflower and half artichoke hearts, all broccoli, half cauliflower and half Brussels sprouts, all cashews and no macadamias, nutritional yeast, Daiya... the possibilities are endless! I usually make it with frozen cauliflower that I cook in the microwave for a couple of minutes until it's not frozen solid anymore. I bake it at 375 degrees F for about 30 minutes or until the cauliflower feels soft when I insert a fork in it. As with all other casserol-y things, I broil it for a minute when it's done.
You wanna take a peek inside?
So deliciously creamy and satisfying! Today's streaming recommendation would have been Gavin and Stacey, because every time I make Mandee's Cauliflower Cheeze it reminds me of the episode when Pam was pretending to be a vegetarian (for the silliest reason) and Gwen makes a chili con carne for everyone else, but Pam gets stuck with a cauliflower cheese - without the cheese because Gwen didn't know if Pam ate dairy, so it was just "cauliflower with a bit of onion." The horror! Pam really wanted that chili and she asked her husband to "smuggle" her some meat! Anyway, Netflix used to have Gavin and Stacey available to watch instantly but they don't anymore. BOOO!
For dessert today we have some sweet Peanut Butter Squares that Mandee's friend found on the interwebz. Chocolate and peanut butter? Yes! Gimme! They are like a deconstructed peanut butter cup! Mandee said that they were super sweet, so I figured I would only use half the amount of sugar called for in the recipe. They weren't impossibly sweet, but they also didn't firm up much without the extra sugar. Doh! My bad. The chocolate was very hard and the peanut butter pretty soft, which made it impossible to cut them into squares without squashing and flattening the peanut butter. I flipped the whole thing upside down (chocolate-side down) and cut them that way instead. It worked!
Today's Duck-of-the-Day picture...
Hey! You're not a duck! This is my mother in law's pup who we shall call Piggly Wiggly to respect his witness protection program rules. This is his Bond, James Bond face. Wiggly, Piggly Wiggly.
21 comments:
Nomnomnom This looks simply far too amazing ;ppReplyDelete
Thanks! I really love this cauliflower cheeze!Delete
I can't decide which of these things I want to eat more!ReplyDeleteReplies
I hope it's not the puppy! :PDelete
Holy crap! I can't imagine anything better than that cauliflower cheeze! I have to make this right away!!ReplyDeleteReplies
Yes, you do! Make it now! Hurry! :DDelete
The cauliflower cheese looks so incredibly delicious. I made cauliflower mac and cheese for a certain four-year-old and she wouldn't eat it though I thought it was yummy. Maybe I'll give this one a shot. Maybe I'll tell her it's cheese pie. It looks like cheese pie. :)ReplyDelete
Seriously cute pup.Replies
It is! It's very mild if you don't add any nutritional yeast or a vegan cheese (I almost always make it without those ingredients) so maybe it will please Miss E's young little taste buds. Cheese pie would be a great name for it! :DDelete
what a great post. That cauliflower dish looks really tasty. And I especially love Piggly Wiggly! Woof/quack!ReplyDeleteReplies
I think Piggly Wiggly and Snoopy would get along great! Piggly Wiggly is also a bit of a Baby Dumb Dumb :DDelete
Squeee, puppy!! So cute! That cauliflower cheese looks amazing too, I haven't made that for years.ReplyDeleteReplies
I think you owe yourself to make some cauliflower cheeze then!Delete
I am so glad you love that cauli-cheese recipe :D It is delicious and I have to remind myself to make it every now and then, it's so comforting!ReplyDelete
And yay for the squidgey pb squares! I have another recipe to try that has less sugar, so hopefully that works out well, too!Replies
Gavin and Stacey! I watched them all! I loved that show, I didn't know anyone else on the planet watched too! I now ask people, "what's occurring?" all the time.ReplyDelete
Oh! What's occurring? That's awesome, Kittee! I also thought I was the only one in the US that watched Gavin and Stacey! Nessa is one of my favorite TV characters ever. She's so funny! Alright Kittee, how's it going, alright? :DDelete
Mmmm cauliflower cheeze. You've made me hungry, i haven't felt hungry in a couple of days so YAY.ReplyDelete
I'd still eat those pb squares, with a spoon if I had to!
I love Gavin & Stacey. Pretty much everything uttered by uncle bryn is comedy gold.Replies
Awesome! I'm glad I could be of help! :DDelete
Uncle Bryn is so hilarious! Bryn and Nessa are definitely the best characters.
- AnonymousOctober 30, 2012 at 11:53 AM
Yummy! I've never come across that recipe on Mandee's blog before, now I need to make it. So creamy!ReplyDeleteReplies
You do need to make it! I love this dish so much! Hopefully I can return the favor - you gave me the fluffiest bread ever and I gave you a link to the creamiest, most delicious casserole ever! :DDelete


text:
New Chevrolet Dealer Serving Cuba City, WI
Runde Chevrolet-Buick-GMC
|Mary B. from Cuba City, WI
|2012 Chevrolet Equinox
|Nik and Ashley W. from Cuba City, WI
|2010 Chevrolet Traverse
|Gary and Sandy A. from Cuba City, WI
|2016 Chevrolet 1500
|Corey C. from Cuba City, WI
|2013 Chevrolet 1500
|Alicia D. from Cuba City, WI
|2010 Chevrolet Malibu
If you hail from the Cuba City, WI area and are searching for a new or used Chevrolet, Runde Auto Group has all the facts and figures you'll need available to you online. We don't just sell Chevrolets - we also service and can order parts for most all makes and models of cars, trucks and vans. You're sure to find what you're looking for at Runde's with one of the largest online vehicle inventories in the heartland of the midwest. Whether you're searching for something that runs on gas, e85, diesel or pure electricity, please check us out to see all we have to offer.
Visit Runde Auto Group online right from your home in the Cuba City vicinity! You'll find the largest vehicle inventory in the region with multiple photos of every new and used Chevrolet in stock. At RundeAutoGroup.com, you're able to shop online, schedule an oil change appointment, apply for auto financing or even appraise your trade-in without ever having to leave your house!
Used Chevrolet Dealer Near Cuba City, WI at Runde Chevrolet-Buick-GMC
Chevrolet has many fuel-efficient models to choose from and Runde Auto Group carries them all. Whether you're shopping for a gas-sipping commuter car or want to get fast and furious in the hottest sports car, Runde is the spot to shop. Browse through our vast selection of online vehicles right from your home in the Cuba Cityarea. You'll be glad you found us – not only do we offer highly competitive pricing, but we NEVER charge doc. fees or any other hidden charges that you might see at other dealerships.
Runde Auto Group doesn't just cater to people in the Cuba City area shopping for a Chevrolet. We deal in many makes and models from the various manufacturers. Give us a call at 866-735-5200 with any questions - whether you're looking to buy a new truck or the car you're currently driving, Runde's has your needs covered.
Runde Auto Group offers Cuba City area residents the lowest prices and competitive finance rates on all new and used cars and trucks. Schedule a test drive with us today. The folks here at Runde's will never let you down! We have sold vehicles to many Cuba City area customers and we'd love the opportunity of helping you find the perfect car, truck, van or SUV.
Chevrolet Service & Repair Near Cuba City, WI
Visit our service department near Cuba City, WI for your routine oil changes and tire rotations. If you need more extensive repair, we also staff many certified Chevrolet technicians who are fully capable of performing the most complex services on your vehicle.
With four separate service locations, over 30 technicians and competitive pricing, going to a Runde service center near Cuba City, WI is one of the best decisions you can make for your wallet and your vehicle.
Chevrolet Parts Near Cuba City, WI
Looking for Chevrolet parts? Visit or call our our parts department near Cuba City, where we'll order the parts your vehicle needs. We will order your parts and give you complimentary calls as soon as your part has arrived in our store. Want it installed? No problem, our service department will be happy to assist you with installing your parts. Our parts department can be reached at 866-735-5200 or you can fill out our parts request form here: Parts Request Form


text:
June 4, 2012
Channel 4 anchor to deliver commencement address
Cabot Rea
NBC4 anchorman Cabot Rea will address the record-breaking class of Spring Quarter 2012 at the commencement ceremony Friday. More than 900 students petitioned to graduate this quarter, with nearly 500 expected to attend the ceremony June 8 at Veterans Memorial, beginning at 10:00 a.m.
It will be the largest spring class on record at Columbus State, and the final Spring Quarter graduation before the college switches to the semester system.
Cabot Rea will address the graduates, along with class valedictorian Sarah Traverse, a summa cum laude (4.0 GPA) graduate from the Veterinary Technology program.
Rea is co-anchor of NBC4 at 5 p.m. with Colleen Marshall and Ellie Merritt and NBC4 at 6 p.m. and 11 p.m. with Colleen Marshall. He joined NBC4 in 1985 as a weekend sports anchor and features reporter. Rea has also served as co-anchor of NBC4 at 6 with Gail Hogan, co-anchor of NBC4 at 7 with Colleen Marshall, co-anchor of The 10
o'clock News airing on WB 53 (WWHO) and field anchor of Live at 5:30. In 2009, he was voted favorite male anchor by readers of Columbus Monthly, making him their favorite anchor every year since 2005.
Prior to NBC4, Rea was employed as a music teacher for Newark City Schools as well as a professional singer and actor. He started his broadcast career by working as a radio announcer while attending college.
Rea graduated from Otterbein College in 1978 with a degree in music education. He also received a Master's degree in Voice Performance from The Ohio State University in Fall 2003. Rea is most proud of twice being named "Teacher of the Year" at Newark Junior High School.
The graduation ceremony is free and open to the public.
8th Annual Ohio Growth Summit focuses on growing business
The 2012Ohio Growth Summit, hosted by the Small Business Development Center at Columbus State, was dedicated to the memory of Denai Downs Vaughn, who had been scheduled to participate as this year's keynote speaker until her unexpected death in November. One of Vaughn's messages was to "Do more. Be more. Achieve more. You are worth it!" and her inspirational words were carried on throughout the Summit.
The event focused on helping individuals start and grow their business, with help from expert keynote speakers such as Paul Evans and Gini Dietrich. During Evans' presentation, he clearly outlined the steps to developing and implementing your own personal success plan. Dietrich discussed a lot of her own trials in owning a business – sharing that it is not always easy, but it is worth it.
Another theme throughout the event was the use of social media to grow and strengthen businesses, and various speakers and panels helped answer participant's questions on the emerging topic. This year the Summit also added outcome-based workshops on social media strategy and placement, strengthening your organization and growing your business, business finance matchmaking, and content marketing strategies.
Since the event, the social media world has been buzzing, including the keynotes. Paul Evans talked about it in his recent podcast, giving major kudos to Mike Bowers and the SBDC team for the work they do. You can listen to his podcast here: http://youtu.be/Yx5lQGDZoCQ. Bowers was also featured on Dietrich's blog, Spin Sucks, as the "Follow Friday" feature: http://spinsucks.com/social-media/followfriday-michael-bowers/. Here's an excerpt from one of her tweets :
To read more about the event visit www.OhioGrowthSummit.com.
Year-end purchasing dates draw near
The Purchasing Department has announced the final dates for the expenditure of Fiscal Year 2012 funds:
Thursday, June 7, 2012 - Last day to create online requisitions for operating, non-capital, purchases.
Friday, June 8, 2012 - Last day to place orders with a vendor for operating, non-capital purchases.
Volunteer opportunities for the golf enthusiast
Do you enjoy working with central Ohio youth? Do you want to make a difference? Volunteer with The First Tee of Columbus!
The First Tee of Columbus is committed to impacting the lives of young people by providing educational programs that build character, instill life-enhancing values and promote healthy choices through the game of golf. Some of the volunteer opportunities this summer include:
Girls Golf
Girls learn values inherent to the game of golf, such as patience, respect, perseverance, and honesty, preparing them to meet challenges of today's world with confidence.
Mondays, 6:00-8:00 p.m., June 4 -25, at Raymond Memorial Golf Course. Participants are girls ages 7-17.
2012 Down Syndrome Golf Academy
The program has been designed to benefit even more members including beginners who are interested in learning the game of golf and advanced golfers who want to improve on the skills acquired through the Academy last year. Participants are ages 12 and older.
Beginners: Wednesdays, June 13 – August 1, from 6:30-8:00 p.m.
Advanced: Tuesdays, June 12 – August 1, from 6:30-8:00 p.m.
Location alternates between Bridgeview Golf Course and Bent Tree Golf Course – you can choose the location to volunteer.
Buckeye Ranch Golf Academy
This program provides a safe and fun environment that creates curiosity about the game of golf while seamlessly integrating essential links between golf and life skills.
Monday – Thursday, June 13 - August 12, from 12:30-2:00 p.m. at Bridgeview Golf Course. Participants are between the ages of 12-17.
If you are interested in volunteering contact Judith Cockrell, email@example.com or call (614) 471-1404.
"Thin clients" and "Print on Demand" come to the Columbus Campus
Students in the Computer Commons are getting their software with a lot less hardware thanks to "thin clients" that were recently installed.
This technology, piloted very successfully at the Delaware campus, has garnered the attention of colleges and businesses from all over the state. The Columbus State Virtual Computing Team recently presented about the Delaware pilot to a packed house at a statewide technology conference.
Thin clients are small terminals that access software and memory from a central server cluster, rather than keeping software and documents on individual desktop computers. The PCs in the Computer Commons--206 in all--have now been replaced with thin clients. To be successful, this technology requires a robust and reliable server and storage network.
The thin clients dramatically reduce support requirements by allowing lab administrators to update the entire lab from a single software image and then push out software fixes to terminal clients immediately. The thin clients use a fraction of the electricity a PC requires and produce much less heat. They also boot up much faster than the old desktops. The technology life span of a thin client is twice that of a PC and is only limited by the power of the servers it is attached to. This extends
the lab computer replacement cycle by at least four years and redirects the technology investment to the server infrastructure which can much more efficiently distribute the total computing power across campus.
Another feature, the Virtual Desktop Interface (VDI), will soon be implemented. The VDI will allow students to access the Computer Commons resources on their home PCs, laptops and other devices that can support the VDI client.
To celebrate the project, the Computer Commons is planning a student celebration on Tuesday, June 5. A separate celebration is planned over break for employees who worked on the project.
In a related project, the Computer Commons has also instituted a "Print on Demand" system to allow students to display a list of jobs they have sent to the printer, select the ones they really need to print, and then print them on demand. Currently, students send a document to the printer, then go over and "release" it by typing in their CougarID. In the old system, printouts were placed in cubbyholes based on a station ID. Many students printed multiple copies then lost or abandoned their unwanted printouts resulting in incredible paper waste. The new system has been quickly adopted and students appreciate not having to wait for print jobs or sort through stacks of paper to find the final copy they really wanted to keep.
Both the print on demand and the thin client projects were done in phases, and the projects never closed the lab. Both projects required close coordination from all departments in Information Technology. Working on the projects were Rob Stailey, Desktop technician; Trish Malloy, System administrator; Rhonda Gurio, supervisor of lab assistants; and Gurio's entire crew of IT support staff assigned to the Computer Commons.


text:
Thank you to all who participated in the Mamma Agata cookbook giveaway. Out of all the great comments about your favorite Italian dishes, I randomly chose #29, Janie's comment (her favorite dish is homemade ricotta ravioli with a simple tomato sauce to remind her of lunch with her grandparents). Janie will be receiving an autographed copy of Mamma Agata's Simple and Genuine Cookbook. And today, for everyone that would like a glimpse at the recipes in the cookbook, I'm sharing one of them, Mamma Agata's Coccoli.
These herb fritters were just one of the amazing antipasti that I tasted during my day cooking on the Amalfi Coast, a simple yet oh-so delicious fried treat. Versions of fritters are a classic starter to Italian meals, especially pizza, and as usual, their names change depending on the region. I've heard them called in pastella in Rome, pasta crescuita in Naples, and pittule in Puglia. Who doesn't love fried batter, golden, crunchy and salty outside with the softest pillow-like savory dough inside?
Mamma Agata takes them to another level adding fresh herbs, parmigiano and pancetta to the batter. The herbs give them a pop of freshness, the parmigiano adds extra cheesiness and the pancetta is a subtle addition of the sweet pork fat flavor. They are perfect little starters to any special meal, even your holiday Christmas dinner, for example. The batter (pastella) can also be used as a dipping batter. Dip a mix of seasonal vegetables or shrimp in the batter; fry them and you will look like a god or goddess in the kitchen with this assortment of antipasti.
Love Neapolitan food and its region? - Join me and taste and cook the best pizza, pasta & pastries this region offers on an 8-day/7-night all-inclusive vacation to the Amalfi Coast!
Food Lover's Amalfi Coast Vacation - Reserve your spot today!
Mamma Agata adding the pancetta, parmigiano and herbs to the coccoli batter
The recipe and exactly how to make the batter and fry it is beautifully illustrated in Mamma Agata's cookbook. In the book you'll find all her secrets to making the coccoli flavorful and how she gets the pillow-like pefection inside while keeping things crunchy outside. She has also dedicated a full page in her book to share her frying secrets. Below is the recipe and then highlights from her frying instructions.
Frying the coccoli during my day cooking with Mamma Agata
If you'd like to order the book, you can order it directly from Mamma Agata's website. Chiara and Mamma Agata share some fabulous family recipes and classics of Neapolitan cuisine. With those recipes, along with the stories and photos in the book, they will transport you to the family's Ravello terrace and views of the Amalfi coastline. It would make a beautiful gift for yourself or that special Italian food lover in your life.
Mamma Agata's Simple and Genuine Cookbook
The terrace at Mamma Agata's Cooking School
Coccoli di Mamma Agata (Herb Fritters)
(from Mamma Agata's Simple & Genuine Cookbook, recipe published here with her permission)
Mamma Agata's Pastella:
2 cups (250 g) "00" flour, or white pastry flour
1 teaspoon (25 g) sugar
3/4 cup (100g) Parmigiano cheese, grated
1 egg
1 cup (200 ml) lukewarm water
1 3/4 tablespoons (25 g) yeast (dry or fresh cake yeast)
2 pinches sea salt
2 teaspoon vinegar
For the Coccoli:
1/2 cup (100g) Parmigiano Regiano cheese, grated
1/2 onion, grated
1 3/4 oz (50 g) pancetta or salami, finely chopped
1 teaspoon finely chopped rosemary
1 teaspoon finely chopped thyme
1 teaspoon finely chopped sage
1 quart (1 liter) peanut or grape seed oil for frying (or another oil with a high smoke point)
To make the pastella: In a bowl, combine the flour, sugar and cheese. Add the egg to the bowl and mix together thoroughly. In a separate bowl, dissolve the yeast into the water. Once the yeast is dissolved into the water, slowly add the yeast mixture to the flour mixture. Combine together with your hands until the mixture is the consistency of a thin pancake batter. (NOTE: If the batter is too thick, add 1 or 2 tablespoons of water; if the batter is too thin, add a little more flour to thicken it.) There will be lumps in the batter, do not try to whisk them out; or you will overwork the dough and get tough fritters. Cover the bowl and set it aside in a warm, draft-free location for one hour.
After one hour, the batter will have risen. Add the vinegar and salt to the batter and stir. (The batter will deflate when stirred; this is normal.)
To make the Coccoli: In a bowl, mix togehter the cheese, onion, pancetta, and herbs. Add this mixture to the pastella batter and mix together just until the ingredients are combined. (Do not overwork the dough.)
Follow Mamma Agata's frying instructions: In a frying pan, heat the oil to 375°F (190°C). Using a tablespoon, gather a tablespoon of batter and place it in the oil, letting the batter slide off of the spoon into the oil. Continue this process until you have around 10 coccoli in the pan (Do not overcrowd the pan or it will reduce the ideal temperature of the oil and the coccoli will absorb too much of the oil and be greasy.) Fry the coccoli on each side for 1-2 minutes, until both sides are golden brown. Remove them from the oil and place on paper towels. These are best served hot. Continue frying the remaining batter in batches in the same manner until you fried all the batter. These are best served hot. Buon appettito!
"I Segreti della Frittura" (Secrets of the Fry)
Mamma Agata's secrets and tips for making Coccoli and for frying:
For the pastella batter and coccoli:
The batter will be lumpy - Don't try to dissolve the lumps or you will overwork the dough and get tough fritters.
The water for the yeast must be lukewarm to the touch. If it's too cold or too hot, it will kill the yeast. The batter will not rise and you will not have pillow-like fritters.
Whenever you make batter or dough with yeast, you must add sugar to activate the yeast.
Mamma Agata uses type "00" flour for all of her recipes. She suggests substituting it with white pastry flour if you can't find "00" flour.
Adding vinegar to the batter helps to inhibit the oil from penetrating during the frying process and preventing the coccoli from being greasy.
Mamma Agata's frying tips:
The best frying pans are ugly! She uses a pan that's about 3 to 4 inches deep and 10 inches across. And, she uses this pan and only this pan for frying, letting it get seasoned with each fry, and also uglier with each fry. Her ugly pan lasts at least 3 to 4 years.
Mamma Agata is generous with the quantity of oil and recommends at least 1 liter or quart for her type of pan. She keeps a space of about 1 inch from the oil leve and the top of the pan and never overcrowds the pan when frying. This can cause the oil temperature to drop and the fritters to take too long to cook and to absorb too much oil.
The temperature of the oil is very important. It should be 375 F or 190 C.
Quality of the oil is also important. Seed oils are best for frying because they have a high smoke point and have a neutral flavor that will not change the flavor of what you are frying. Mamma Agata uses peanut oil. She never uses olive oil for frying.
She always uses "clean" oil and never reuses oil from a previous day's or meal's frying.
Related Posts You Might Also Like:
Cook with Me and Italian Mammas in Puglia in 2013
Torta Caprese - Flourless Chocolate Cake from Capri
Nutella Filled Venetian Frittelle
Pasta alla Genovese and Other Neapolitan Pasta Sauces at Citta del Gusto
Neapolitan-Style Mussels (Cozze alla Marinara)
A Drive Along the Amalfi Coast


text:
Office Stamps
Do you mark documents with certain office words often? Our Office Stamps will help you keep papers and documents organized. Get clear, crisp impressions without using a separate ink pad. These office stamps don't just impress with its appealing design -- it's also the world's first climate-neutral stamp! This office stamp is not just unbelievably small and light, but also consists of up to 65%* post-consumer recycled plastic. In comparison with previous model, 49%* reduction in carbon emissions during manufacture. The residual, unavoidable carbon footprint is compensated by Trodat's investment in Gold Standard climate protection projects recommended by the WWF. The fully transparent viewing window provides a clear view when positioning and aligning the stamp for perfectly placed imprints. These office stamps are available in seven exciting colors and imprint options include: First Class, Copy, Rush, Media Mail, Confidential, Paid, and Draft.
Clean, Intuitive Ink Cartridge Change
Two special grip zones allow a cartridge to be exchanged without touching the ink reservoir--for guaranteed clean fingers.
Incredibly Small and Light
The Office Stamp is one of the world's smallest and lightest self-inking stamps. Soft-touch elements guarantee a pleasant, secure stamp grip.
Precise Imprint Positioning
The Office Stamp's crystal-clear positioning window enables accurately placed imprints. The transparent bottom edges allow for precise alignment.
The new grips ensure the clean handling and insertion of the ink pad without touching the cartridge insert. If you already own a Trodat 4912 Office Stamp and are running low on ink, visit the replacement ink pad product for this specific stamp model. Also visit the Notary Public Underwriters YouTube Channel to see how to properly replace this notary stamp's ink pad.
Our highly skilled production department is committed to quickly and accurately producing the best quality custom products. If you have any questions about our line of custom products, please don't hesitate to contact our customer service team today!
*ECO-black and ECO-grey. Lower percentage for other colors.
Product Specifications
Office Stamps