Racket simple AE define-type - racket

From the book "Programming Languages: Application and Interpretation" page 6 I try to code the very first example in DrRacket
#lang typed/racket
(define-type AE
[num (n number?)]
[add (lhs AE?) (rhs AE?)]
[sub (lhs AE?) (rhs AE?)])
But I get the error
aeinterpretter.rkt:5:2: define-type: unexpected term in: (add (lhs AE?) (rhs AE?))
What am I doing wrong here?

You should run this example in the PLAI language:
#lang plai
(define-type AE
[num (n number?)]
[add (lhs AE?) (rhs AE?)]
[sub (lhs AE?) (rhs AE?)])
The Typed Racket language is a totally different language that gives you most of the power of the base Racket language, but with a static type system. The define-type form in PLAI is a different notion of "type".

Related

Dependent contracts for structs in Racket

Suppose I define a struct for a set with its "center".
(struct centered-set (center elems))
I want to guarantee the following conditions.
elems is a set.
center is an member of elems.
I can express the conditions with #:guard. Is there a way to express the same conditions as a contract?
For functions, ->i works as a combinator for that kind of dependent contracts. How to express dependent contracts for structs?
IIUC, contract-out doesn't support anything like that. However, you can simulate the functionality by providing the constructor and accessors manually with the contract attached:
#lang racket
(module foo racket
(provide (contract-out [bt (-> any/c any/c any/c (bst/c 1 10))]
[bt-val (-> (bst/c 1 10) any/c)]
[bt-left (-> (bst/c 1 10) any/c)]
[bt-right (-> (bst/c 1 10) any/c)]))
(define (bst/c lo hi)
(or/c #f
(struct/dc bt
[val (between/c lo hi)]
[left (val) #:lazy (bst/c lo val)]
[right (val) #:lazy (bst/c val hi)])))
(struct bt (val left right)))
(require 'foo)
(bt 11 #f #f)
It should be possible to write a provide transformer to automate this process.

Applying cast to dynamically required function in typed racket

I'm trying to load and use a function from a different module at run-time. The issue is that dynamic-require's range, Any, can't seem to be casted to a more specific (function) type.
test.rkt:
#lang typed/racket
(module other-module typed/racket
(provide f)
(: f : Integer -> Integer)
(define (f x)
(* x 2)))
; g has type Any because dynamic-require returns a value of type Any
(define g (dynamic-require '(submod "test.rkt" other-module) 'f))
;contract violation
; Attempted to use a higher-order value passed as `Any` in untyped code: #<procedure:f>
; in: Any
; contract from: typed-world
; blaming: cast
; (assuming the contract is correct)
((cast g (-> Integer Integer)) 3)
Is there any way to load and use a function at run-time from a different module in #lang typed/racket?
One work-around is to do the loading in an untyped module and use require/typed to assign types:
#lang typed/racket
(module other-module typed/racket
(provide f)
(: f : Integer -> Integer)
(define (f x)
(* x 2)))
(module another-module racket
(define g (dynamic-require '(submod "test.rkt" other-module) 'f))
(provide g))
(require/typed 'another-module
(g (-> Integer Integer)))
(g 3)
;; 6
But yeah, it would be nicer if dynamic-require could take a target type or Typed Racket allowed untyped regions (the opposite of with-type).

Error in defining contract on struct in Racket

I'm trying to define a contract for a struct which inherits from another struct.
#lang racket
(require racket/contract racket/contract/parametric)
(struct semigroup (op))
(struct monoid (mempty) #:super struct:semigroup)
(define (semigroup/c a) (struct/dc semigroup [op (-> a a a)]))
(define (monoid/c a)
(struct/dc monoid [mempty a] [(op #:parent semigroup) (-> a a a)]))
I get an error
struct/dc: expected an identifier that names a field or a sequence with a field name, the #:parent keyword, and the parent
struct
at: (op #:parent semigroup)
in: (struct/dc monoid (mempty a) ((op #:parent semigroup) (-> a a a)))
I fail to see what I'm doing wrong.
I'm using Racket 6.9.

extend racket syntax for backus-naur-forms

I have a set of derivation rules implemented in racket. We can assume that there aren't any optional , which means there are no rules containing pipes (in BNF): ::= |
In racket, I have got something like this:
(define *rules*
'((S . ("b" "a"))
(B . ("a"))
(C . (S B))))
Please note that terminal symbols are implemented in the form of racket strings, nonterminal symbols in the form of racket symbols. Now, I'd like to import this rules from another racket file containing rules in backus naur syntax:
S ::= ba
B ::= a
C ::= SB
(capital letter = nonterminal)
Therefore, I need to extend the racket syntax. I have no idea how to handle that. Can you help me? It shouldn't be that much code ...
I think you're looking to parse a file that's written using the BNF syntax, and produce an s-expression version; is that right?
If so, it shouldn't be hard. In particular, the format implied by your question is that every line is of the form
<NT> :: = [<NT>|<T>]*
... which you could take apart like this:
#lang racket
;; COPYRIGHT 2012 John B. Clements (clements#brinckerhoff.org)
;; Licensed under the Apache License, version 2.
;; (You're free to use it, but your source code has to include
;; my authorship.)
(require rackunit)
(define example
(list "S ::= ba"
"B ::= a"
"C ::= SB"))
;; parse a single line:
;; string -> (list/c symbol? (listof (or/c string? symbol?)))
(define (parse-line l)
(match (regexp-match #px"^([A-Z]) ::= ([A-Za-z]*)$")
[(list _ lhs rhses)
(list lhs (map parse-char (string->list rhses)))]))
;; parse a single char:
;; char -> (or/c symbol? string?)
(define (parse-char ch)
.. oops! out of time. You'll have to write this part yourself... )
(check-expect (map parse-line example)
'((S ("b" "a"))
(B ("a"))
(C (S B))))
Oops! I see a bug in there. No problem, you'll figure it out. Gotta run....

hc-append unbound identifier in module in

Hello I am following the quick introduction to racket. In chapter 5 they propose that this code (which worked fine):
(define (four p)
(define two-p (hc-append p p))
(vc-append two-p two-p))
would tipically be written by using let, so I wrote my code:
#lang slideshow
(define (square n)
(filled-rectangle n n))
(define (four p)
(let ([two-p (hc-apppend p p)])
(vc-append two-p two-p)))
but it doesn't work.
The error message is:
expand: unbound identifier in module in: hc-apppend
Just checking: Did you remember
#lang slideshow
as the first line?
Also, count the number of p characters! It is hc-append. The error mentions hc-apppend: it should be hc-append.