[HN Gopher] Show HN: A design-by-contract Python package in ~100...
       ___________________________________________________________________
        
       Show HN: A design-by-contract Python package in ~100 lines
        
       Greetings! A 2.5 weekends project to teach myself newer Python
       features (>= 3.10). Conditions are written as Lambda expressions
       that annotate parameters and return types, and coexist with type
       annotations. Symbols to share values between conditions are also
       supported to a limited extend.
        
       Author : stefanka
       Score  : 53 points
       Date   : 2022-07-12 11:43 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | greatgib wrote:
       | To me it is not smart to use that. You make the code complicated
       | that it will be unreadable. Normally the code should speak for
       | itself. This is the key strong point of python.
       | 
       | Also, then you need annotation and tests to validate your
       | annotations!
        
         | hansvm wrote:
         | The example of dimension checking is handy, especially in
         | fields where the same name for an idea has multiple
         | incompatible instantiations or when there's an arbitrary choice
         | that some subfield uses and some other makes differently (left
         | vs right multiplication as a convention, left vs right handed
         | coordinates as a convention, tensor ordering, ...). Sometimes
         | better names help, but often they're just a lot of visual noise
         | for the tiny bit of additional information they portray.
         | Usually I use strings as type annotations for that purpose
         | (compactly describing common constraints like the shape's
         | shape, which dimensions are in common, ...) to communicate to
         | other developers, but I could see a use case for some actual
         | tooling, especially to the extent that somebody could build on
         | top of the library and tailor it to some problem domain.
         | 
         | def foobar(a: '(i>1, j)', b: '(j, k)') -> '(k,)':
        
           | stefanka wrote:
           | Seems you refer to a domain specific language in the
           | annotations. This is exactly what
           | https://github.com/AndreaCensi/contracts does (it's an
           | amazing project but has a very large code base). However, I
           | wanted to achieve something similar in pure python and as
           | compact as possible - so there are compromises (like no real
           | symbolic calculus)
        
         | stefanka wrote:
         | Fair. I personally prefer to see the expectation to the
         | arguments (especially in a scientific / data science context)
         | over looking into asserts in the function body, which distract
         | from the algorithm in there. Originally, I planned to
         | automatically include the lambdas in the docstring/sphinx but
         | unfortunately, Python does not keep the source code of the
         | lambda (only the whole line and parsing would be overkill). I
         | did not understand your second remark, could you clarify
         | please?
        
       | manimino wrote:
       | Interesting. Are the conditions checked at runtime on each call
       | of the function?
        
         | stefanka wrote:
         | Thanks! Yes, it is for runtime checking only
        
           | IshKebab wrote:
           | Then what's the advantage compared to normal assertions,
           | which I think would be a lot more readable.
           | 
           | I think normally this sort of thing is useful so you can
           | statically check stuff. If it's runtime only that seems a bit
           | useless.
        
           | dachryn wrote:
           | what is the performance overhead? especially on recursive
           | calls
        
             | stefanka wrote:
             | Let's say I did not put a focus on speed-and there will be
             | a performance overhead ontop of the actual checks. In a
             | production system, you should probably consider to
             | deactivate it in performance-critical parts
             | (evaluate=False)
        
       | tpoacher wrote:
       | When most people hear design by contract, they predominantly
       | think preconditions. Maaaaaybe postconditions.
       | 
       | But in fact the most crucial aspect of contracts for me is
       | invariants.
        
       | masukomi wrote:
       | I love DBC and use it in racket all the time. Saves me so much
       | time & frustration. So yay, and congrats on making this.
       | 
       | How does using this effect performance? [edit: strike that i see
       | that in another comment you said you don't know]
       | 
       | I remember someone wrote one of these for ruby and the
       | performance impacts of their implementation were just brutal.
       | Like, 2x slower or something (it was a long time ago). Dunno if
       | it was a bad implementation or just something about ruby.
        
         | stefanka wrote:
         | Thanks! I will have to run some tests very soon I guess. I
         | usually handle functions that do some heavy number crunching
         | where the overhead seems less important. I expect some impact
         | but also see some space for optimization through caching.
        
       ___________________________________________________________________
       (page generated 2022-07-13 23:02 UTC)