On 09/14/2015 10:48 AM, Stefan Monnier wrote: >> Representing errors more conventionally is cheap. > > AFAIK "representing errors more conventionally" means wrapping every > single function we pass to the module API. That's definitely not cheap > in terms of performance. Yes, we need an internal condition-case at the boundary between the module API and the Emacs core. I can call setjmp 54 million times per second. (100000000 runs in 183ms.) Performance is simply not a problem. >> If there's even a small chance that I'm right about the safety and >> maintainability advantages of using purely local exits, > > Representing errors as exceptions also has advantages. Besides performance? Longjmp for error handling has an _expressiveness_ advantage in the Emacs core, but that's because we use GC data structures for everything. Not so with external modules. >> why not err on the side of caution? AFAICS, there's no advantage to >> using non-local exits and plenty of risks. > > There are very many advantages, on the contrary. In a non-local exit scheme intended for use with third-party code and not supported by any standardized exception system (like C++ exceptions or SEH), I see only risks. > > Also, I expect most module authors will be familiar with Emacs, and > having to learn a different style will be an extra hindrance. I expect them to be familiar with Emacs. There is no need to make module developers familiarize themselves with Emacs internals. The public API should insulate them from that. > >>> But the issue only comes up once these non-Emacs libraries call back to >>> Emacs functions (i.e. step 5 in my example). So only those calls need >>> to be protected somehow from non-local exits. >> Calls back to Emacs functions will be fairly common, because modules use >> these functions to manipulate Emacs data on behalf of their own callers. >> Any of these functions can quit. What you're imagining will be a rare >> case will in fact be common. > > You're not talking about the "step 5" case. You're talking about the > Emacs-specific module code calling Emacs functions. Indeed, this will be > very common. But to write this code, you will have to know a fair bit > about Emacs internals, anyway. It will not look like your "typical C++ > code". Why shouldn't it? We _can_ make it look just like typical C++ code, and to encourage module development, we should. Why make life harder for people? >> I also don't think it's correct that the Emacs-specific module code will >> work properly in the presence of modules. You're supposing too much >> patience and knowledge on the part of third-party module authors who'll >> want to provide bindings not only for Emacs, but for other systems as well. > > I don't forsee droves of coders who no nothing about Emacs internals and > who start writing third party modules. Plenty of developers know nothing about Java or Python or Ruby or C# or V8 internals and write native extensions for these systems. Supporting developers who know the Lisp side of Emacs and who don't want to be bothered working in core is one of the most important use cases of the module system. > > In any case, I think it would be easy to layer the kind of API you > imagine on top of the kind of API I imagine, whereas the reverse seems > to be much more difficult and/or much less efficient. On the contrary, layering a different non-local exit scheme on top of an error flag scheme is elegant. Imagine a C++ module library that throws a C++ exception upon returning from Emacs and seeing the error flag set, the translates (just before returning from C++ to Emacs) that C++ exception back into an Emacs error. Now you have a non-local error scheme that is exactly the right thing for both languages. > So I'd rather we go with a straightforward lean API for a start. > And we can develop an alternative API on top afterwards (it might even > be possible to implement this alt-API as a module). A local-exit-only API _is_ a lean API, at least from a semantics perspective. It's not surprising. The cost of the error flag machinery in terms of both performance and API specification space is minuscule as well. >>> Of course it is. We already do that in Emacs's core with things like >>> safe_call. >> safe_call blindly suppresses errors. > > You're nitpicking. Of course we'd use something slighly different which > stores the error somewhere. Th point remains that it's easy to provide > such a wrapper. So now we need some kind of explicit error propagation machinery *anyway*, plus we're making developers worry about non-local exits. Let's skip the latter part. > >> Errors from module-invoked functions to propagate normally from the >> perspective of surrounding Lisp code. > > [ Is there a verb missing, maybe, I can't quite parse this, sorry. ] s/to // I don't want C-g to break when module, core, and lisp frames are mingled on stacks, and I expect these situations to be fairly common, especially if we support modules with names like "python" and "guile".