In theory, the latter does the same thing, but it's far more explicit, the developer knows it relies on the network and accordingly that it may fail. Developers will be more inclined to plan for errors when the possibility of such errors are more obvious.
So in most cases you'd do something like:
let foo = () => http.GET('/foo');
.
.
.
foo() //foo is statically dispatched in the source code hereIs it really a useful distinction? Let's rename our 'foo()' to 'dangerously_unreliable_with_unpredictable_latency_foo()'. Is there still a huge difference?
> accordingly that it may fail. Developers will be more inclined to plan for errors when the possibility of such errors are more obvious.
That part of your comment looks suspiciously similar to the usual argument against exception handling to me.
And to your second point... yes, all developers should check possible exceptions, just like all children should brush their teeth. However, if you have bad habits and you aren't good all the time, then at lease brush your teeth after eating sweets, and likewise, developers should please check for exceptions around network calls.
Access the RPC call as httpSerbice.getFoo() and make it return a Future/Promise, or even a special subtype of those. 100% obvious what it does.
You're going to be calling REST methods the same exact way anyway - you have to pass around the result of that restful http.get call somehow.
int start(void (*job)(void*), void (*done)(void*), void* tag);
`job` is called on a separate thread at some point (goes through a job scheduler) and once it is done, `done` is called at the "main" thread (at some synchronization point, usually during the event loop), `tag` is just passed around for context. `start` returns zero on failure.I don't see RPCs as anything different conceptually (after all the job might also fail). The only issue someone might have is when expecting a synchronous API, but even in non-networked code there are tons of asynchronous APIs.
The goal should be to inform the caller of the types of errors that may pop up. Obviously, with network or RPC calls, the caller should handle the case where the network is down. With threaded apps, the potential errors are more subtle, but the caller should definitely be aware that it's not a synchronous call. The function header you proposed is a bit clumsy due to the c semantics, but gets the general point across well enough.
The part I find most interesting about Fielding's thesis[1] is the introduction with architectural overview. He managed to map out modern Web apps perfectly - they can be REST (Web app with db/storage backend, perhaps extended with something like webdav) which is amenable to multilevel caching, smart client;movable data: json api js app, or smart client;movable code: js/Ajax - executing js delivered by server on client (subtly different from a "pure" js/json app (which is similar to an XML/xslt App).
I don't know why the hype of rest lead people to insist on conflating their architectures.
[1] http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Ed: not sure about "time wasted bickering over it". Bickering is always time wasted. Careful analysis of software architecture, patterns, and figuring out what you're actually trying to achieve - is time well spent.
There are fundamental trade-offs between REST and different patterns - depending on where the truth of your data recides, if you need acid or not, and where (what part of) your code executes.