Le vendredi 5 mai 2017 15:24:40 UTC+2, Matthias Felleisen a écrit : > See > https://docs.racket-lang.org/style/Units_of_Code.html#%28part._.Modules_and_their_.Interfaces%29
That's a very interesting document, thanks for the reference. Would you suggest that, in this spirit, types for functions are moved to the top of the file with the provide forms, instead of being specified alongside each function? > > On this topic, I have sometimes written recursive functions with expensive > > contracts (when recursing down a list, a contract on the whole list will > > have a total cost of O(n²)). > > 2. I consider this a horrible idea and I made sure define/contract does not > do so. If you feel that unsure about recursive functions, I recommend using > types. They help you avoid typos at that level. I'm using types wherever possible. Unfortunately, TR does not (yet) mix well with contracts (but I'm aware that there is a pending PR for this). More importantly, Typed Racket cannot be used to write macro implementations, for several reasons: * Lack of immutable values at the type level (this means that values with type Syntax can in principle contain mutable values, which break occurrence typing) * syntax/parse (and possibly syntax/case) have not been ported to Typed Racket. I did in the past a couple of experiments to use Typed Racket to implement macros, but the results were unsatisfactory. My best attempt so far, tr-immutable/typed-syntax (still unstable and undocumented) requires "unsafe" mutable syntax values to be converted to a "safe" representation, and converted back after executing the macro. When writing complex compile-time transformations, I felt the need to check the input and output of every recursion step, to catch the exact point at which an error occurs. I'm genuinely unsure which aspect of this idea you find horrible? * Is it because the contract is specified along the function, with define/contract-out, instead of being written alongside the provide forms? If so, separating the contract from the function definition, using a form similar to TR's (: name type), would allow the contract to be specified next to the provide form, but still have it applied to recursive function calls during debugging. * Is it because turning off the contract for recursive calls would lower the safety (i.e. the swim vest analogy)? In my case, the contract on the result was strong enough to catch the error anyway, and the goal was only to catch incorrect results as soon as possible, instead of waiting until they cross the module boundary and are returned to the original caller, so that it is easier to locate the exact source of the error. * Is it because of something else that I missed? In conclusion, I do agree that types are a much better option, and I do use them wherever possible. Unfortunately, there are some cases where types cannot be used (yet), and in those cases I'd like to get as much help as I can from contracts when debugging, without imposing a horrendous cost during normal development (which does not mean tossing all safety aside, but rather allow errors to be caught at module boundaries instead of detecting them nearly immediately). These goals do not seem insane to me, and I'm 100% open to suggestions on how to achieve this :) . -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.