3

I am writing a function that accepts only positive numbers, and I want to ensure that it is used correctly both inside the module and elsewhere.

I wanted to write

#lang typed/racket
(require racket/contract)

(: excited-logarithm (-> Number Number))
(define/contract (excited-logarithm ([x : Number]) : Number)
  (-> (>=/c 0) number?)
  (displayln "Hold on to your decimals, we're going in!")
  (log x))

but Typed Racket doesn't provide its own define/contract, and vanilla define/contract doesn't understand Typed Racket's annotations (it throws a syntax error).

Can I work around this somehow? Can I use bare contract to attach a contract to excited-logarithm the way define/contract would?

Moreover, is there a good reason I shouldn't be doing this? Is mixing contracts and types discouraged?

Note: I suppose what I really want here is dependent typing, but that's not available in Racket.

shadowtalker
  • 12,529
  • 3
  • 53
  • 96

1 Answers1

2

Simple answer here: use the type "Nonnegative-Real", or one of the other similar TR Types that capture this idea.

http://docs.racket-lang.org/ts-reference/type-ref.html?q=Positive-Real#%28form._%28%28lib.typed-racket%2Fbase-env%2Fbase-types..rkt%29..Positive-.Real%29%29

(There are also refinement types, but you don't need them, here.)

John Clements
  • 16,895
  • 3
  • 37
  • 52
  • Wow, I missed these in the reference, thanks! The question does remain for the general case, however. – shadowtalker Oct 30 '17 at 00:50
  • It depends on how general your "general" case is. You can use refinement types to capture some constraints like this, and you can certainly define your own simple flat-contract macro to perform this check; most of the interesting/challenging parts of contracts happen for function types. – John Clements Oct 30 '17 at 02:58
  • 1
    What are "refinement types"? I searched for that term in the Typed Racket docs and didn't find anything. – shadowtalker Oct 30 '17 at 03:01
  • For the general case where a specific type does not exist, [intersection types](https://docs.racket-lang.org/ts-reference/type-ref.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types-extra..rkt%29._~e2~88~a9%29%29) might be a possibility. – ben rudgers Oct 30 '17 at 03:56
  • @ssdecontrol It's an "experimental feature" in 6.10. Here's the URL for the docs: https://docs.racket-lang.org/ts-reference/Experimental_Features.html?q=refinement#%28form._%28%28lib._typed-racket%2Fbase-env%2Fbase-types-extra..rkt%29._.Refinement%29%29 – John Clements Oct 31 '17 at 18:59