3

I am using Racket contract system, and I want to export a function of no arguments, which returns a lambda expression with no arguments, e. g.:

#lang racket
(define (foo)
  (do-somthing)
  (lambda ()
    (do-other things)))

Does anyone know how to write contract for this kind of function?

skaffman
  • 398,947
  • 96
  • 818
  • 769

1 Answers1

2

I suspect it would look something along the lines of:

#lang racket/load

(module m racket
  (provide/contract [foo (-> (-> any/c))])
  (define (foo)
    (+ 10 3) ; do something
    (lambda ()
      (+ 40 2) ; do other things
      )))

(module n racket
  (require 'm)
  ((foo)))

(require 'n)

(-> (-> any/c)) is a contract that matches functions that returns another function, which, when evaluated, returns a single integer value.

But if you'd like to relax return values of foo, you'd use just any instead of any/c, which allows any number of return values, not just a single value. Consider:

(module m racket
  (provide/contract [foo (-> (-> any))])
  (define (foo)
    (+ 10 3) ; do something
    (lambda ()
      (values (+ 40 2) 666); do other things
      )))

See Contracts on Higher-order Functions in Racket documentation.

YasirA
  • 9,531
  • 2
  • 40
  • 61
  • Oops, to be precise, the contract in the first example should've been written like `(-> (-> integer?))` to match a function without arguments, which in turn returns another function without arguments before finally returning an integer. The contract `any/c`, in contrast, accepts any *single* value, including `integer?`; for instance, `symbol?`, `list?` etc. – YasirA Feb 21 '11 at 08:04
  • Note that one possible problem of `any/c` is that it introduces a wrapper layer and some cost, whereas `any` does not. – Eli Barzilay Feb 21 '11 at 08:18
  • Thanks for the reply! It works, I used the (-> (-> any)). Then I am starting to suspect, 1. The contract like above, it doesn't say much about the function, especially using "any" ? 2. I may be wrong, but currently, using the contracts is like explicitly imposing type info on functions, data structures and then the contract system checks violation in runtime. However, recall the imperative programming language, like C, those information need to be specified when you write code, and compiler can check it in compile time, which I think it is more efficient than FP, like Racket..... –  Feb 21 '11 at 18:31
  • 1
    @freezdom: It's not only about type, it's also about a value. Consider, for example, a predicate `positive?`; a contract `(-> positive?)` would check that function returns positive values. In C, you would check this explicitly using conditions `if .. then .. else`. Though there are [tools and libraries for C](http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_third-party_support) to use contracts. – YasirA Feb 21 '11 at 18:51