
lazy and REST seem to go together :) Perhaps this will expose my ignorance of laziness/strictness and isn't at all Yesod specific. I have a handler that can serve html or json. When an html request comes in it still executes the json code. I assume this is because the json code uses liftIO. What is the strategy for avoiding executing the json code?

On Thu, Jan 6, 2011 at 5:29 AM, Greg Weber
lazy and REST seem to go together :) Perhaps this will expose my ignorance of laziness/strictness and isn't at all Yesod specific. I have a handler that can serve html or json. When an html request comes in it still executes the json code. I assume this is because the json code uses liftIO. What is the strategy for avoiding executing the json code?
Let me start with the theoretical response: if you have both an HTML and JSON representation for a resource, they should be giving *exactly* the same data, just in a different format. Therefore, there should just be a pure function applied to some data to generate the JSON version, and thus no extra processing should be performed (due to laziness) when giving an HTML response. Therefore, your problem doesn't exist ;). Of course, in theory, theory and practice are the same, but in practice they're not. Sometimes it *is* necessary to provide slightly different data, and producing that data will require some IO action. There are a few approaches: * What you have right now: run actions for both the HTML and JSON versions, and let Yesod pick the correct result afterward. This is slightly inefficient, but easy to program. * Provide two different resources, one providing only HTML, the other only JSON. Depending on how different your representations are, this might make sense. * If the actions can be run inside the IO monad and don't require a full Handler monad, there is some tricky stuff you can do involving enumerators. This is not often necessary. In theory this is an area where Yesod could provide a nicer interface for users. In practice, the problem doesn't come up very often, and therefore I don't have enough experience to know what a good interface would be. I'd like to hear (even in private) a more detailed explanation of what you're trying to accomplish here. Michael

Thanks for the detailed response. My application essentially has permalink
routes that end up rendering the same html as a non-permalink route, but the
permalink route does indicate some existing state. Right now it is coded so
the permalink route will grab the extra state over a separate JSON request.
The problem being that the original html request also gathered the JSON. I
suppose my current setup is not truly RESTful and the html response should
render the state instead of using an extra JSON call, although I do find
this a convenient technique. One way or another I should be able to change
things to avoid the extra IO.
On Thu, Jan 6, 2011 at 1:20 PM, Michael Snoyman
On Thu, Jan 6, 2011 at 5:29 AM, Greg Weber
wrote: lazy and REST seem to go together :) Perhaps this will expose my ignorance of laziness/strictness and isn't at all Yesod specific. I have a handler that can serve html or json. When an html request comes in it still executes the json code. I assume this is because the json code uses liftIO. What is the strategy for avoiding executing the json code?
Let me start with the theoretical response: if you have both an HTML and JSON representation for a resource, they should be giving *exactly* the same data, just in a different format. Therefore, there should just be a pure function applied to some data to generate the JSON version, and thus no extra processing should be performed (due to laziness) when giving an HTML response. Therefore, your problem doesn't exist ;).
Of course, in theory, theory and practice are the same, but in practice they're not. Sometimes it *is* necessary to provide slightly different data, and producing that data will require some IO action. There are a few approaches:
* What you have right now: run actions for both the HTML and JSON versions, and let Yesod pick the correct result afterward. This is slightly inefficient, but easy to program. * Provide two different resources, one providing only HTML, the other only JSON. Depending on how different your representations are, this might make sense. * If the actions can be run inside the IO monad and don't require a full Handler monad, there is some tricky stuff you can do involving enumerators. This is not often necessary.
In theory this is an area where Yesod could provide a nicer interface for users. In practice, the problem doesn't come up very often, and therefore I don't have enough experience to know what a good interface would be. I'd like to hear (even in private) a more detailed explanation of what you're trying to accomplish here.
Michael

Without knowing all the inner workings, it sounds like this is a good
case to move the JSON response to a separate resource.
On Thu, Jan 6, 2011 at 11:50 PM, Greg Weber
Thanks for the detailed response. My application essentially has permalink routes that end up rendering the same html as a non-permalink route, but the permalink route does indicate some existing state. Right now it is coded so the permalink route will grab the extra state over a separate JSON request. The problem being that the original html request also gathered the JSON. I suppose my current setup is not truly RESTful and the html response should render the state instead of using an extra JSON call, although I do find this a convenient technique. One way or another I should be able to change things to avoid the extra IO.
On Thu, Jan 6, 2011 at 1:20 PM, Michael Snoyman
wrote: On Thu, Jan 6, 2011 at 5:29 AM, Greg Weber
wrote: lazy and REST seem to go together :) Perhaps this will expose my ignorance of laziness/strictness and isn't at all Yesod specific. I have a handler that can serve html or json. When an html request comes in it still executes the json code. I assume this is because the json code uses liftIO. What is the strategy for avoiding executing the json code?
Let me start with the theoretical response: if you have both an HTML and JSON representation for a resource, they should be giving *exactly* the same data, just in a different format. Therefore, there should just be a pure function applied to some data to generate the JSON version, and thus no extra processing should be performed (due to laziness) when giving an HTML response. Therefore, your problem doesn't exist ;).
Of course, in theory, theory and practice are the same, but in practice they're not. Sometimes it *is* necessary to provide slightly different data, and producing that data will require some IO action. There are a few approaches:
* What you have right now: run actions for both the HTML and JSON versions, and let Yesod pick the correct result afterward. This is slightly inefficient, but easy to program. * Provide two different resources, one providing only HTML, the other only JSON. Depending on how different your representations are, this might make sense. * If the actions can be run inside the IO monad and don't require a full Handler monad, there is some tricky stuff you can do involving enumerators. This is not often necessary.
In theory this is an area where Yesod could provide a nicer interface for users. In practice, the problem doesn't come up very often, and therefore I don't have enough experience to know what a good interface would be. I'd like to hear (even in private) a more detailed explanation of what you're trying to accomplish here.
Michael
participants (2)
-
Greg Weber
-
Michael Snoyman