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.

Reply via email to