Creating -unsafe dependant array/string/bigarray access primitives#113
Creating -unsafe dependant array/string/bigarray access primitives#113thomasblanc wants to merge 1 commit intoocaml:trunkfrom
Conversation
|
I find the name |
|
Well, there is no clear convention about how those primitives should be named:
So I opted for a name that would clearly state the variable behavior. I agree that |
|
I would be glad this could be added in conjuction with a |
|
If this PR gets merged (or maybe #69), we may need to fix the warning in pparse.ml. Currently the compiler warns about using |
|
@dbuenzli (quoting your mantis comment)
My understanding is a bit different. What you ask on mantis is for a way to turn all unsafe construction into safe constructions (not unlike the debug assertions we have in the runtime that are turned off in production builds). That's a good idea, but it requires more work; for example What would be your desired semantics for the |
|
@thomasblanc in the #69 discussion @lpw25 suggested using |
|
Le samedi, 1 novembre 2014 à 18:15, gasche a écrit :
Well separate compilation is separate compilation. If you are using a module that uses a library that wasn't compiled with the switch there may still be uses of unsafe primitive and I'm fine with this. As I explain in my comment what I want is to be able to turn unsafe primitive uses into safe ones for the code of a particular module without having to modify the source code. Maybe -safe is misleading, -no-unsafe-primitives that affect the Daniel |
fcf5052 to
eae55da
Compare
@gasche done ! @dbuenzli : well, that's a different and kind of heavy feature you're asking for here. I really don't see how you could replace |
|
Le lundi, 3 novembre 2014 à 14:39, Thomas Blanc a écrit :
As I said, it's not really about making everything safe, it's really about making these primitives that have a safe and unsafe version (e.g. array accesses) force to use the safe ones. See my comment on mantis for the motivation. |
|
This patch looks good to me. It could be quite useful. |
|
So indeed we were able to merge #69 directly -- in no small part due to @thomasblanc's high-quality review of the patch, which I'm proud to note happened during a "ocaml compiler hacking" meetup :-) |
|
Since #69 finally isn't merged into trunk, should we reopen this discussion? From the (long) discussion there, it seems to me that this subset of the proposal doesn't cause any trouble. Yet it is also far less powerful. |
|
@damiendoligez , any opinion on this? I would be in favor of merging. @thomasblanc : sorry for the bikeshedding, but when I got your message I re-read the patch and I could not remember what the |
|
That's not a problem, I'll wait to see if there is a fixpoint to the name-choosing before commiting the change :-p |
|
Since the compiler option is for switching to the unsafe mode, would |
|
Indeed, |
|
This is the world I would like to be in:
In this world, there is no "switched" or "opt" calls: each call is either safe or unsafe by default, and can be changed from the command line, so I know we're not in this world yet, but if we could move into that direction I'd be happy. Re: separate compilation, it's a compile-time flag, it cannot change what was compiled before. So I pretty much agree with @dbuenzli on every point so far. |
|
Maybe a good first step would be to add a pair of command line switches |
|
@damiendoligez I either don't understand or don't agree with what you propose. In my mind it is important that the programmer be able to explicitly say "this must be a safe access", and not be overriden by some global decision. (On the other hand I recognize the need to make everything safe for debugging purposes; I'm not saying the situation is symmetric.). In my mind, this is what |
|
A global -unsafe, with no way of insisting on safeness under the programmer's control at the call site, can make badly-written but not actually buggy code segfault. Since checked array accesses raise an exception, we might expect to be able to usefully catch it, rather than it always being fatal. For example, here's some code for Floyd-Steinberg dithering, which spreads errors around an image. Errors "fall off the edge" leading to bad array accesses. Now, I wouldn't release such awful code, and there are other ways of writing it, but it does exist... |
|
Indeed, I have written some not-unsimilar code in the past. Another case is when you expose an API to your users that assumes some precondition on usage bounds and is not defensively programmer to check them, but instead delegate to the underlying access/update calls of the implementation to fail safely in case of misuse. (Again this is not optimal code, as arguably showing the underlying error to the programmer is not nice, but we can be rather sure there is such code in the wild.) |
I don't see the argument here with existing code in the wild. The point is not to start to compile everything with The model @damiendoligez wants to expose is a simple and clear one. I could actually get away with the |
And yet that's what we have now with I'm a lot more interested in the part about adding |
Is the current situation not slightly different? It is possible to insist on safeness by using the long form |
That's right, and it's quite wrong that the function called by |
Please don't, make the system easy to reason about. Here's a simple model to understand:
As far as |
|
@damiendoligez: always-unsafe does not seem very useful. There should always be a way to force safety. |
Why ? Again 1) as a programmer you are not supposed to make out of bounds accesses and 2) this is only supposed to be applied on selected modules.
That's exactly what I don't want. I want to be able to code with safe primitives and once I have convinced or proved that all my accesses are safe, be able to compile the module with -unsafe to get the performance (which was significant for decoders last time I measured). |
That's your opinion, not mine. If I write a long running server, I don't want it to fail completely or to reply wrong answers, just because I used a library that was written by somebody who thought he was smarter than other ones and could use unsafe accessors everywhere, even when I use
That's what Anyway, as I said, the semantics of .() should be to always raise an exception, so that a user that expects bound-checks on array accesses, as advertised by OCaml, does not see segfaults or wrong results when using |
Absolutely not, we precisely agree on this, compiling with I disagree that |
|
@lefessan I now see that I had read your "always-unsafe does not seem very useful." as "always-safe ...". I still think two primitives and the model I propose should be enough. At least "always-unsafe" should really not exist, we want the guarantee when we compile with |
|
Indeed, it looks like we are actually agreeing on the most important, i.e. removing |
Use stateful scanning_action for minor GC and promotion.
|
Nearly 4 years later, is there a conclusion from this discussion, and possible actions? If the conclusion is "we should deprecate then remove the |
|
@xavierleroy if I remember correctly, it was decided in a dev meeting to go with #69 instead (it should have been closed at the time). This PR willingly did not change anything other that "making any decision we would take about |
c703f5f Incorporate upstream comments into type-variable refactor (ocaml#121) 362ba23 Constrain curry modes to increase along applications (ocaml#108) b1f0cf9 Simplify the extension handling (ocaml#114) 4fd53a1 Remove pat_mode from typedtree (ocaml#105) cf6fcbc Handle attributes on lambdas with locally abstract types (ocaml#120) 5fa80fe Don't track attributes inside attributes for warning 53 (ocaml#115) 8a69777 Handle unclosed `[: ... :]` patterns (via `Generic_array` machinery) (ocaml#117) b0737f4 Add promote-one Makefile target (ocaml#118) c6ad684 Refactoring and fixes around module lookup (ocaml#107) b0a6495 Add documentation for global constructor arguments (ocaml#69) dd79aec Print `nlocal` in the `-d(raw)lambda` output (ocaml#112) 8035026 Fix `nlocal` in the generated Lambda for list comprehensions (ocaml#113) afbcdf0 Immutable arrays (ocaml#47) bfe1490 fix several issues when removing exp_mode (ocaml#110) 8f46060 Better error message for under-applied functions (ocaml#74) 27331d8 Consistently use Lmutvar or Lvar in comprehensions (ocaml#111) 01e965b Skip failing test for now 0131357 Fix test case to use comprehensions_experimental 22a7368 Temporarily disable list comprehensions tests due to locals bug e08377d Make `comprehensions` into `comprehensions_experimental` for now (ocaml#109) 947cf89 List and array comprehensions (ocaml#46) bd9e051 remove exp_mode from typedtree (ocaml#100) a9268d2 Fix misplaced attribute warning when using external parser (and some cleanup) (ocaml#101) 2b33f24 Refactor toplevel local escape check (ocaml#104) ed2aec6 Comment functions exported from TyVarEnv. 87838ba Move new variable creation into TyVarEnv. a3f60ab Encapsulate functions that work with tyvars 43d83a6 Prevent possibility of forgetting to re-widen 2f3dd34 Encapsulate context when narrowing type env't d78ff6d Make immediate64 things mode cross (ocaml#97) aa25ab9 Fix version number (ocaml#94) d01ffa0 Fix .depend file (ocaml#93) 942f2ab Bootstrap (ocaml#92) 05f7e38 Check Menhir version (ocaml#91) 1569b58 Move the CI jobs from 4.12 to 4.14. (ocaml#90) git-subtree-dir: ocaml git-subtree-split: c703f5f
After discussion with @planar and @gasche, here is a small patch that adds some new primitives to the compiler.
Basically %array_switched_get behaves as %array_safe_get unless the -unsafe option is activated, in which case it behaves as %array_unsafe_get.
It is inspired from the last commit by @Octachron (see #69) and may help remove the syntactic trick used for array/string/ba access.