Closed jwiegley closed 10 years ago
Thanks, this looks great! Although I can't say I understand all the control stuff. For testing we could try replacing import Shelly
with import Shelly.Lifted
in the existing tests.
@gregwebs Everything looks done for this first cut. I finished the remaining todo items:
Shelly.Lifted
now re-exports every function that Shelly
exports, providing lifted variants wherever possible.MonadShControl
instances. Sometime you and I should get on Skype or Hangouts, and I can go into depth about what these are doing._sh
variants of the exception handling functions now just use lifted-base
and enclosed-exceptions
(for safety with regard to async exceptions), and are marked deprecated with a pointer to those functions.Shelly.Lifted
instead of Shelly
, and everything seems to be working great. I did not add this change to the pull request, however.I actually want to use this functionality in a tool I'm writing, where I want to use a ReaderT r Sh a
, so porting my code is the next step for me.
It's still unfortunate to have a doubly-nested ReaderT
, just to carry around things like command-line option values. But I can't think of anything at the moment which doesn't introduce a lot more complexity. After all, most of the time spent in Shelly
will be executing processes, rather than the extra overhead of a nested Reader.
After all, most of the time spent in Shelly will be executing processes, rather than the extra overhead of a nested Reader.
yep, I have never heard a complaint about speed or CPU usage, just memory.
Looks great, thank you! I will wait for word on how porting your code goes.
I think we should create a flag for the test suite that will change the import with CPP so that both can be tested.
Ok, I will both port my code and conditionalize the tests today, and then we'll see how it goes. I think the Lifted layer is so "zero logic" that unless I've gotten some of the instances wrong, it should be pretty solid.
yeah, that is why I don't think we need to automatically run it every time by default, but just have it as a flag.
@gregwebs I've ported my application to using this type:
type App a = ReaderT Options Sh a
It worked like a charm! I didn't have to change any code except to remove all the Options arguments in my functions. This did reveal one minor bug, which I've fixed above.
When compiling this, I get:
src/Shelly/Base.hs:77:10:
Not in scope: type constructor or class `Catch.MonadThrow'
Is there a version bound missing?
Very possibly. I'll try to get that fixed tonight. In fact, I need to add lower and upper version bounds for all the new dependencies.
Hi Greg!
Here is the very first cut. I'm submitting this as a pull request simply to begin a conversation on the best direction(s) for the code to go in. I intentionally have not finished it yet, because at this point I just wanted to prove that the concept works, and to get your feedback.
Here is what I have working now:
lifted-base
andlifted-async
, you can freely useasync
,try
,catch
, etc., withinSh
blocks. This does not require importingShelly.Lifted
, but works with existing code. This eliminates the need forasyncSh
and the other_sh
variants of the exception handling functions.import Shelly.Lifted
, all the higher-order functions (likesub
,withTmpDir
, etc.) can work within any of the standard transformers (MaybeT
,StateT
, etc).liftSh
function, for lifting functions written inSh
rather than abstracted overMonadSh
.What's left to do:
Shelly.Lifted
for every function inShelly
, abstracting them overMonadSh
. The goal here is to avoid the need to useliftSh
with any of Shelly's own functions. The real purpose ofliftSh
is to allow users to call their own functions written inSh
.MonadShControl
instances. The need for these instances is truly a hideous thing, but users will never see it, and it gives us great flexibility. Basically, we are usingMonadBaseControl IO
to allowlifted-base
andlifted-async
to work, andMonadShControl
to allow things like the newly abstractedsub
to work. I had to fork my own Shelly-specific brand ofmonad-control
to do this, because you can't have two bases (lifted-async
needs to see IO as the base, andsub
needs to seeSh
as the base)._sh
exception handling variants as deprecated.There is only about 3 hours more work left to do, but I wanted you to have a chance to review what I've done so far, to see if the approach is even acceptable to you.