In Haskell at least you do not have to explicitly yield. Instead, any call to the garbage collector is treated as a possible yield point (so it's possible to hog a CPU if you write a non-allocating loop).
Not sure what to say about your second point: you do have to store context for the other fibers, but only in the same way you have to pay to store the context of an OS thread or pending callback.
>Don't you trade for a different type of complexity in yield/resume?
That depends on the library in question. Generally the event/callback style code people are writing are only "yielding" at calls to the non-blocking version of otherwise blocking functions, like read type functions, or accept. Most userland threading libs I've seen make the assumption that you want that, and so you don't need to yield yourself. If you did want that level of control, it is still simpler than the event style of achieving the same result.
>Also you will lost some of the scalability advantages because you have to store context for all of the idle fibers.
The overhead is small, especially if you know you don't need much stack and set the thread stack size lower.
Also you will lost some of the scalability advantages because you have to store context for all of the idle fibers.