Evaluation of the contractor’s dependence on the contract twice?

#lang racket

(module inside racket
  (provide
    (contract-out
      [dummy (->i ([x       (lambda (x) (begin (displayln 0) #t))]
                   [y (x)   (lambda (y) (begin (displayln 1) #t))]
                   [z (x y) (lambda (z) (begin (displayln 2) #t))]
                   )
                  any
                  )]
      )
    )

  (define (dummy x y z) #t)
  )

(require 'inside)

(dummy 1 2 3)

Output signal

0
0
1
1
2
#t

I don’t understand why for xand yfor dependencies it is required that the corresponding defender starts again.

Document ->i http://docs.racket-lang.org/reference/function-contracts.html#%28form._% 28% 28lib.racket% 2Fcontract% 2Fbase..rkt% 29.- ~ 3ei% 29% 29 , it seems does not mention this.

Can anyone shed some light on this?

+4
source share
1 answer

It was just as strange to me as it was to you, so I took the opportunity to ask this question on the Racket mailing list . The following is an attempt to summarize what I found.

->i , -, . , , , , , , .

. - , . :

> (define/contract (foo x)
    (integer? . -> . string?)
    (number->string x))
> (foo "hello")
foo: contract violation
  expected: integer?
  given: "hello"
  in: the 1st argument of
      (-> integer? string?)
  contract from: (function foo)
  blaming: anonymous-module
   (assuming the contract is correct)

- ; :

> (define/contract (bar x)
    (integer? . -> . string?)
    x)
> (bar 1)
bar: broke its own contract
  promised: string?
  produced: 1
  in: the range of
      (-> integer? string?)
  contract from: (function bar)
  blaming: (function bar)
   (assuming the contract is correct)

. ->i : .

->i , . :

(->i ([mk-ctc (integer? . -> . contract?)])
      [val (mk-ctc) (mk-ctc "hello")])
     [result any/c])

, , . promises mk-ctc , (mk-ctc "hello") ! , , , , , .

:

#lang racket

(module m1 racket
  (provide ctc)
  (define ctc
    (->i ([f (integer? . -> . integer?)]
          [v (f) (λ (v) (> (f v) 0))])
         [result any/c])))

(module m2 racket
  (require (submod ".." m1))
  (provide (contract-out [foo ctc]))
  (define (foo f v)
    (f #f)))

(require 'm2)

ctc m1, , , m2. :

  • foo , f #f, , (integer? . -> . integer?) . , foo:

    > (foo add1 0)
    foo: broke its own contract
      promised: integer?
      produced: #f
      in: the 1st argument of
          the f argument of
          (->i
           ((f (-> integer? integer?))
            (v (f) (λ (v) (> (f v) 0))))
           (result any/c))
      contract from: (anonymous-module m2)
      blaming: (anonymous-module m2)
       (assuming the contract is correct)

    Ive , , , m2, . , .

  • ctc ! , v f v, , v . , v - , f . 1 , v:

    > (foo add1 "hello")
    foo: broke its own contract
      promised: integer?
      produced: "hello"
      in: the 1st argument of
          the f argument of
          (->i
           ((f (-> integer? integer?))
            (v (f) (λ (v) (> (f v) 0))))
           (result any/c))
      contract from: (anonymous-module m1)
      blaming: (anonymous-module m1)
       (assuming the contract is correct)

    (Racket " " ), ! m1, . indy.

- , , . : , -.

, . , ->i ​​, , , , (, - , , ).

, , , ( , , ), , , ->i , .


1. , ->d , add1 . ->i ->i ->d.

+4

Source: https://habr.com/ru/post/1663754/


All Articles