how to make contract for a non-empty hashtable - racket

Racket has a non-empty-listof contract but no non-empty-hashof contract. Is there a way to build one?

Predicates can be used as contracts, so:
(define (non-empty-hash? x)
(and (hash? x)
(not (hash-empty? x))))
Then you can use non-empty-hash? as your contract.

You can use contract logical operators like and/c and not/c to build the desired form instead of using a predicate function (Similar to the way mutable datatypes are checked for in contract):
Welcome to Racket v8.7 [cs].
> (define (non-empty-hash/c key/c val/c)
(and/c (hash/c key/c val/c) (not/c hash-empty?)))
> (define/contract x (non-empty-hash/c symbol? number?) (hash))
x: broke its own contract
promised: (not/c hash-empty?)
produced: '#hash()
in: the 2nd conjunct of
(and/c
(hash/c symbol? number?)
(not/c hash-empty?))
contract from: (definition x)
blaming: (definition x)
(assuming the contract is correct)
at: string:1:17
[,bt for context]
> (define/contract x (non-empty-hash/c symbol? number?) (hash 'a 1))
> x
'#hash((a . 1))
or just (and/c hash? (not/c hash-empty?)) if you don't want to constrain the key and value types.

Related

What is the use of `,` and `,#` in Racket?

I'm new to Racket and I was hoping to get more insights in the these two operators: , & ,#.
There's very little documentation of these new operators, however, to my understanding the former (,) unquotes everything if its is followed by a list. And the latter (,#) splices the values.
For example if the following is typed in the Dr. Racket interpreter:
(define scores '(1 3 2))
(define pets '(dog cat))
and then the following query is made:
`(,scores ,#pets)
this would yield : '((1 3 2) dog cat)
It would be appreciated if I could get more details, definitions and more examples about these operators.
Thanks in advance.
A single quote followed by the written representation of a value
will produce that value:
Example:
'(1 x "foo")
will produce a value that prints as (1 x "foo").
Suppose now that I don't want a literal symbol x in the list.
I have a variable x in my program, and I want to insert
the value to which x is bound.
To mark that I want the value of x rather than the symbol x,
I insert a comma before x:
'(1 ,x "foo")
It won't work as-is though - I now get a value that has a literal comma as well as a symbol x. The problem is that quote does not know about the comma convention.
Backtick or backquote knows about the comma-convention, so that will give the correct result:
> `(1 ,x "foo")
(1 3 "foo") ; if the value of x is 3
Now let's say x is the list (a b).
> `(1 ,x "foo")
(1 (a b) "foo") ; if the value of x is (a b)
This looks as expected. But what if I wanted (1 a b "foo")
as the result? We need a way so show "insert the elements of a list".
That's where ,# comes into the picture.
> `(1 ,#x "foo")
(1 a b "foo") ; if the value of x is (a b)
They are "reader abbreviations" or "reader macros". They are introduced in the section of the Racket guide on quasiquotation. To summarize:
`e reads as (quasiquote e)
,e reads as (unquote e)
,#e reads as (unquote-splicing e)
Because Racket's printer uses the same abbreviations by default, it can be confusing to test this yourself. Here are a few examples that should help:
> (equal? (list 'unquote 'abc) (read (open-input-string ",abc")))
#t
> (writeln (read (open-input-string ",abc")))
(unquote abc)
A more exhaustive description of the Racket reader is in the section on The Reader in the Racket Reference. A list of reader abbreviations is in the Reading Quotes subsection.

How deterministic is Racket's evaluation order?

I would like to known how deterministic Racket's evaluation order is when set! is employed. More specifically,
Does #%app always evaluates its arguments from left to right?
If no, can the evaluation of different arguments be intertwined?
Take, for instance, this snippet:
#lang racket
(define a 0)
(define (++a) (set! a (add1 a)) a)
(list (++a) (++a)) ; => ?
Could the last expression evaluate to something different than '(1 2), such as '(1 1), '(2 2) or '(2 1)?
I failed to find a definite answer on http://docs.racket-lang.org/reference.
Unlike Scheme, Racket is guaranteed left to right. So for the example call:
(proc-expr arg-expr ...)
You can read the following in the Guide: (emphasis mine)
A function call is evaluated by first evaluating the proc-expr and all
arg-exprs in order (left to right).
That means that this program:
(define a 0)
(define (++a) (set! a (add1 a)) a)
(list (++a) (++a))
; ==> (1 2)
And it is consistent. For Scheme (2 1) is an alternative solution. You can force order by using bindings and can ensure the same result like this:
(let ((a1 (++ a)))
(list a1 (++ a)))
; ==> (1 2)

Unique identifier for Racket objects?

Is there a way to get a unique identifier for an object in Racket? For instance, when we use Racket's eq? operator to check whether two variables refer to the same object, what identifier is it using to achieve this comparison?
I'm looking for something like python's id function or Ruby's object_id method, in other words, some function id such that (= (id obj) (id obj2)) means that (eq? obj obj2) is true.
Some relevant docs:
Object Identity and Comparisons
Variables and Locations
Is eq-hash-code what you want?
> (define l1 '(1))
> (define l2 '(1))
> (eq? l1 l2)
#f
> (eq-hash-code l1)
9408
> (eq-hash-code l2)
9412
There's a way to get a C pointer of an object via ffi/unsafe, with the obvious caveat that it's UNSAFE.
;; from https://rosettacode.org/wiki/Address_of_a_variable#Racket
(require ffi/unsafe)
(define (madness v) ; i'm so sorry
(cast v _racket _gcpointer))
To use it:
(define a (list 1 2))
(define b (list 1 2))
(printf "a and b have different address: ~a ~a\n"
(equal? (madness a) (madness b))
(eq? a b))
(printf "a and a have the same address: ~a ~a\n"
(equal? (madness a) (madness a))
(eq? a a))
(printf "1 and 1 have the same address: ~a ~a\n"
(equal? (madness 1) (madness 1))
(eq? 1 1))
Though the pointer is not a number or an identifier. It's an opaque object... So in a sense, this is kinda useless. You could have used the real objects with eq? instead.
I also don't know any guarantee of this method. In particular, I don't know if the pointer will be updated to its latest value when the copy GC copies objects.
Here is an implementation of such a function using a weak hash table.
Using a weak hash table ensures that objects are garbage collected correctly
even if we have given it an id.
#lang racket
(define ht (make-weak-hasheq))
(define next 0)
(define (get-id x)
(define id (hash-ref ht x #f))
(or id
(begin0
next
(hash-set! ht x next)
(set! next (+ next 1)))))
(get-id 'a)
(get-id 'b)
(get-id 'a)
Note that Sylwester's advice is sound. The standard is to store the value directly.
You most likely won't find an identity, but the object itself is only eq? with itself and nothing else. eq? basically compares the address location of the values. So if you want an id you can just store the whole object at that place and it will be unique.
A location is a binding. Think of it as an address you cannot get and an address which has an address to a object. Eg. a binding ((lambda (a) a) 10) would store the address location of the object 10 in the first stack address and the code in the body just returns that same address. A location can change by set! but you'll never get the memory location of it.
It's common for lisp systems to store values in pointers. That means that some types and values doesn't really have an object at the address, but the address has a value and type encoded in it that the system knows. Typically small integers, chars, symbols and booleans can be pointer equal even though they are constructed at different times. eg. '(1 2 3) would only use 3 pairs and not any space for the values 1-3 and ().

Does racket allow for function overloading?

I am new to Lisp-scheme and fairly new to the functional paradigm as a whole, and am currently doing an assignment which requires me to overload a function with the same name, but different sets of parameters in racket. Below is an example of what I'm trying to achieve:
#lang racket
(define (put-ball-in-box two-by-fours nails ball)
... )
(define (put-ball-in-box box ball)
... )
These are not the actual functions, but close enough. As implied, both functions would put a ball in a box, but one would assemble the box from its components first, then call the other. Obviously, when I try the above in DrRacket or using the command line, I get a module: duplicate definition for identifier ... error.
Is there a way to achieve this in racket?
Maybe the answer is right in front of me, but I have spent the last two hours searching for this and couldn't find anything, so would appreciate any pointers.
Thank you.
It doesn't in the usual sense of "writing another definition somewhere else."
It allows shadowing, which is defining a procedure with the same name as an imported procedure. Thus you can (define + ...) and your definition of + will hide the + from racket/base. If you want the original procedure, then you can do something like the following, where I define + to be either addition or string-appending.
#lang racket/base
(require (rename-in racket/base (+ base:+)))
(define (+ . args)
(if (andmap string? args)
(apply string-append args)
(apply base:+ args)))
Another thing you can do is use racket/match to have different behavior based on the shape of the argument.
#lang racket/base
(require racket/match)
(define (fib . arg)
(match arg
[(list n) (fib n 1 0)]
[(list 1 a b) a]
[(list 0 a b) b]
[(list n a b) (fib (sub1 n) (+ a b) a)]))
This second example still doesn't quite do what you want since you have to go to the original definition point and modify the match clauses. But it might be sufficient for your purposes.
A more complicated example would be to use custom syntax to create a define/overload form. But I think you'll find the racket/match solution to be best.
You have the concept of default values as in JS and PHP:
(define (fib n (a 0) (b 1))
(if (zero? n)
a
(fib (sub1 n) b (+ a b))))
(fib 10) ; ==> 55
Now if you had 5 optional parameters you need to order them and even pass some values just to be able to add a later one. To avoid that you can use keywords:
(define (test name #:nick [nick name] #:job [job "vacant"])
(list name nick job))
(test "sylwester" #:job "programmer")
; ==> ("sylwester" "sylwester" "programmer")
Now Racket has classes. You can call a method like (send object method args ...).
(define circle%
(class object%
(super-new)
(init-field radius)
(define/public (area)
(* radius radius 3.1415))))
(define cube%
(class object%
(super-new)
(init-field side)
(define/public (area)
(* side side))))
(define circle (new circle% [radius 7]))
(define cube (new cube% [side 7]))
(map
(lambda (o) (send o area))
(list circle cube))
; ==> (153.9335 49)
Notice that the two classes hasn't really commited to a joint interface with area so this is pure duck typing. Thus you can make a function that expects a class that implements a message and it doesn't need to worry about other aspects of the class at all.

How to bind a contract to anonymous class definition

I have a method which returns class definitions:
(define (max-tracker%)
(let ([current-maximum 0])
(class object%
(init val) ; <--
...
(define held-value 0)
(set-val val)
(define/public (set-val newval) ; <--
(when (newval . >= . current-maximum)
(set! current-maximum newval))
(set! held-value newval))
...
)))
how do I bind a contract to the set-val method?
You can use the with-contract form, which lets you create arbitrary contract regions in expressions:
(define (max-tracker%)
(with-contract
max-tracker-procedure
#:result contract-expr
(class object% (init val) ...)))
This creates a contract region named max-tracker-procedure that exports exactly one anonymous value that must adhere to the contract specified in contract-expr. In this case you could specify a class/c contract. Multiple values and exports can be specified too, by using Racket's ability to return multiple values and using #:results (contract-expr ...) instead. Here's a simpler example demonstrating this:
(define test-value
(with-contract test
#:result (or/c integer? symbol?)
"neither int nor symbol - should break contract"))
Running this should give you:
broke its contract:
promised: (or/c integer? symbol?)
produced: "neither int nor symbol - should break contract"
in: (or/c integer? symbol?)
contract from: (region test)
blaming: (region test)
Combining this with class/c should give you what you're looking for.
EDIT
Here's an example closer to what you'd like:
(define (with-greeting class%)
(with-contract with-greeting
#:result (class/c [greet (->m string? string?)])
(class class%
(super-new)
(define/public (greet person)
(string-append "Hello, " person "!")))))
(define simple-greeter% (with-greeting object%))
(define simple-greeter (new simple-greeter%))
(send simple-greeter greet "Jack")
(send simple-greeter greet 'Jack)