tag:blogger.com,1999:blog-8288194986820249216.post2175176405049438645..comments2024-02-04T15:47:25.088-08:00Comments on Abstract Heresies: A harder puzzleJoe Marshallhttp://www.blogger.com/profile/03233353484280456977noreply@blogger.comBlogger4125tag:blogger.com,1999:blog-8288194986820249216.post-77549308120507508112011-02-23T19:30:42.424-08:002011-02-23T19:30:42.424-08:00Fortunately defining callWithResource is no more p...Fortunately defining callWithResource is no more painful than calling it:<br /><br /><Result, Exn extends Throwable> Result callWithResource(FunctionThrowing<Resource, Result, Exn> f) throws Exn {<br /> Resource r = null;<br /> try {<br /> r = obtainResource();<br /> return f.call(r);<br /> } finally {<br /> if (r != null)<br /> returnResource(r);<br /> }<br />}Arcane Sentimenthttps://www.blogger.com/profile/04144052171693893368noreply@blogger.comtag:blogger.com,1999:blog-8288194986820249216.post-43010348095443780572011-02-23T18:50:41.687-08:002011-02-23T18:50:41.687-08:00I'm surprised this works:
interface FunctionT...I'm surprised this works:<br /><br />interface FunctionThrowing<Arg, Res, Exn extends Throwable> {<br /> Res call(Arg a) throws Exn;<br />}<br /><br />So, if you duplicate callWithResource (and other high-order functions) with exception-throwing variations, you can make this work, at least until someone wants to throw two exceptions:<br /><br />return pool.callWithResource(new FunctionThrowing<Resource, Answer, BadRequest>() {<br /> public Answer call(Resource r) throws BadRequest { return computeAnswer(x, r); }<br /> });<br /><br />This maybe isn't an improvement. (And I'm starting to sympathize with the people who advocate using only RuntimeExceptions.)Arcane Sentimenthttps://www.blogger.com/profile/04144052171693893368noreply@blogger.comtag:blogger.com,1999:blog-8288194986820249216.post-34080768669724573242011-02-23T16:47:44.011-08:002011-02-23T16:47:44.011-08:00So let's assume something analogous for method...So let's assume something analogous for method2. That's the easy part. Now abstract it (e.g. with generics).Joe Marshallhttps://www.blogger.com/profile/03233353484280456977noreply@blogger.comtag:blogger.com,1999:blog-8288194986820249216.post-23188263963667900952011-02-23T16:05:47.226-08:002011-02-23T16:05:47.226-08:00Doesn't the callWithResource way still work? I...Doesn't the callWithResource way still work? It's just clunkier:<br /><br />return pool.callWithResource(new Function<Resource, Answer>() {<br /> Answer call(Resource r) { return computeAnswer(x, r); }<br /> });<br /><br />...with the obvious definitions of callWithResource and Function, and — oh, wait, that's a checked exception, isn't it. So we have to wrap it. Ouch:<br /><br />public Answer method1 (int x) throws BadRequest {<br /> try {<br /> return pool.callWithResource(new Function<Resource, Answer>() {<br /> Answer call(Resource r) {<br /> try { return computeAnswer(x, r); }<br /> catch (BadRequest e) { throw new RuntimeException(e); }<br /> }<br /> });<br /> } catch (RuntimeException e) {<br /> if (e.getCause() instanceof BadRequest)<br /> throw e.getCause();<br /> else<br /> throw e;<br /> }<br />}<br /><br />...except that this could possibly mistakenly unwrap an exception someone else wrapped, so theoretically it should use a private wrapper class...Arcane Sentimenthttps://www.blogger.com/profile/04144052171693893368noreply@blogger.com