Data enforcing in scheme - scheme

In my implementation below of vector and line segment, it seems weird the way that I'm using car and cdr in my implementation of seg-start and xcor. It seems too general, or is this the way loosely typed languages work? For example, I can't say get the xcor of just only a car of a vector.
(define make-vector cons) // accept 2 numbers and make a vector.
(define make-segment make-vector) // 2 vectors connected to make a segment.
(define seg-start car)
(define seg-end cdr)
(define xcor car)
(define ycor cdr)
(define vector1 (make-vector 1 2))
(define vector2 (make-vector 3 4))
(define seg1 (make-segment vector1 vector2))
(xcor (seg-start seg1))
(ycor (seg-start seg1))

If your Scheme implementation supports records (SRFI 9) or structs, it's often better to use that rather than just cons cells or vectors. (Though, records and structs usually use vectors behind the scenes, but that's an implementation detail.)

If make-vector is defined:
(define make-vector list)
and make-segment:
(define make-segment list) ; don't redirect through `make-vector`
Then the accessors can be
(define seg-start first)
(define seg-end second)
and
(define xcor first)
(define ycor second)
The advantage is that it becomes easy to extend the system and add a z coordinate or create a polygons or series of connected vectors without rewriting the code. Cons cells will reduce memory usage slightly, but if you're running out of RAM in an age of cheap gigabytes, it may be time to look at rewriting critical sections in C.

Using cons, car and cdr is not bad, but users of that interface might face weird errors when they try your interface on bad data. I usually start using simple objects this way and move on the second I need more. you can combine this with a tag to be able to make type checking. eg.
(define pair-tag (list 'pair))
(define (kons a d) (cons pair-tag (cons a d)))
(define (kons? x) (and (pair? x) (eq? (car x) pair-tag)))
(define (kar x) (if (kons? x) (cadr x) (error "not a kons")))
(define (kdr x) (if (kons? x) (cddr x) (error "not a kons")))
There are ways to make new types with SRFI-9 Record types. You'll typically get type checking and the error messages gets better without having to do it yourself.
For a full object system and OO programming you can go for TinyCLOS.
Depending on your implementation that code might need some tweaking but I did get it working on Racket R6RS once (I think it runs out of the box for Ikarus)

Related

Does specifying the number of elements on defining a vector in Racket make the program use less time or memory?

For example, can this
#!/usr/bin/env racket
#lang racket/base
(define vector-of-pleasures #6("eating" "cold showers" "swimming" "running" "pullups" "weighlifting"))
(for ((pleasure vector-of-pleasures)) (displayln pleasure))
be more performant because of the optional annotation than this
#!/usr/bin/env racket
#lang racket/base
(define vector-of-pleasures #("eating" "cold showers" "swimming" "running" "pullups" "weighlifting"))
(for ((pleasure vector-of-pleasures)) (displayln pleasure))
?
Methinks it should not matter since in both snippets vector-of-pleasures is immutable.
What are, other than performance, possible reasons for annotating the number of the elements of the vector on its definition?
No, it doesn't. The real use of that syntax is that it lets you write a vector of a bunch of identical things easily: #6(1) is a vector of 6 1s.
But I think it could save space. I can't see why, for instance:
(let ((v #2((1 2))))
(eq? (vector-ref v 0) (vector-ref v 1)))
should not be true. But then this rapidly turns into the question of when similar literals can be folded: can (eq? '(1 2) '(1 2)) return true for instance? I don't know what Racket's rules are on that.

How to calculate the degree of a polynomial in scheme?

I need to create a scheme code that allows me to calculate the degree of a polynomial and show it, is there a special function in scheme that allows me to treat them?
pd: What is the way to raise these types of problems?
There is no such function just like there are no functions for guns in games in the standard libraries. There isn't even one data structure for a polynomial.
As with all user defined extensions you have the power to model your data as you wish and you make an interface to work with that data. This is how you extend the language to support the data you want to play with.
;; this is not part of the interface
(define tag-point (list 'point))
;; these are the interface
(define (point x y)
(list tag-point x y))
(define point-x cadr)
(define point-y caddr)
(define (point? p)
(and (pair? p)
(eq? (car p) tag-point)))
;; implemented distance that uses the interface
(define (distance p1 p2)
;; (assert (and (point? p1) (point? p2)))
(sqrt (+ (square (- (point-x p1) (point-x p2)))
(square (- (point-y p1) (point-y p2))))))
(distance (point 3 0 ) (point 0 4)) ; ==> 5
Now you can change your data structure as long as the interface stays intact:
;; implement points using complex numbers
(define (point x y) (make-rectangular x y))
(define (point-x p) (real-part p))
(define (point-y p) (imag-part p))
(define (point? p) (complex? p))
One could just do (define point make-rectangular) but then the interface documentation would be vague.
In the SICP videos I remember they did a polynomial type. It's in part 4B. It explains pretty much the same as I do here and they actually implement polynomials as a type you can do arithmetic on. Thus it might not be what you are looking for, but their data structure can give you an idea.

Racket count occurrences using `map`

Write a Racket function count-occurrences that consumes two lists of symbols and produces a list of
natural numbers measuring how many times items in the first list occur in the second list. For example:
(count-occurrences (list 'a 'b 'a 'q) (list 'r 'a 'b 'e 'b 'g))
=> (list 1 2 1 0)
I've been struggling with this question - how do I use map to do it, since for this question it's specified we can't use recursion.
My original idea was to do the following:
(define (count-occurrences los1 los2)
(map
(length (filter (lambda (x) (symbol=? x (first los1))) los2))
los1))
but using length here can only get us the number 'a occurred, instead of going into recursion. and for abstract functions there can only be one argument for the inside function, so I'm totally lost.
If ... x ... is an open formula, i.e. an expression which references an unbound variable x, wrapping it in a lambda form makes it a function in x, like so:
(lambda (x) ... x ... )
where x becomes bound by that lambda form; a parameter to this so called lambda function, which is to say, an anonymous function introduced by a lambda form.
So, the solution for your troubles is quite simple: recognize that
(length
(filter (lambda (x)
(symbol=? x (first los1)))
los2))
should actually be
(length
(filter (lambda (x)
(symbol=? x y))
los2))
where y refers to each of the elements of los1 in turn, not just the first one; and that it is then an open formula in y – that is to say, y is unbound, free, there. So we must capture it, and make it bound, by ... yes, enclosing this expression in a lambda form, thereby making it a function in y! Like so:
(lambda (y)
(length
(filter (lambda (x)
(symbol=? x y))
los2)))
And this is what gets mapped over los1.
With this simple tweak, your code becomes a correct, working function definition.
Does this fit your requirements and restrictions?
(define (count-occurrences lst1 lst2)
(map (lambda (e1)
(count (lambda (e2) (eq? e1 e2))
lst2))
lst1))
A good way to keep track of keys and values is with a hash-table. While it is possible to write count-occurrences using map and passing a lambda, being explicit may make it easier to see what is going on.
;;; list list -> list
;;;
(define (count-occurrences keys values)
;; Create data structure
(define ht (make-hash))
;; Initialize data structure with keys
;; Set the value of each key to zero
;; Since we have not started counting
(for ([k keys])
(hash-set! ht k 0))
;; Iterate over values and
;; Increment hash table if
;; When value is a key
(for ([v values])
(if (hash-has-key? ht v)
(hash-set! ht v (+ (hash-ref ht v) 1))
null))
;; Iterate over keys and
;; Create list of values
(for/list ([k keys])
(hash-ref ht k)))
Since recursion is prohibited, explicitly looping may make for more maintainable/readable code than an implicit loop. Besides, the variations of for are worth knowing. Hash tables have the advantage that duplicate keys read the same value and there is no need to track the same key twice.
One of the engineering advantages of using for rather than map is that it is easier to reason about the running time. The running time for this code is 2m + n where m is keys and n is values. Solutions using map will typically be m * n. There's nothing inherently wrong with that. But it is worth recognizing.

How can I unsplice a list of expression into code?

I have an experiment for my project, basically, I need to embedded some s-expression into the code and make it run, like this,
(define (test lst)
(define num 1)
(define l (list))
`#lst) ; oh, this is not the right way to go.
(define lst
`( (define num2 (add1 num))
(displayln num2)))
I want the test function be like after test(lst) in racket code:
(define (test lst)
(define num 1)
(define l (list))
(define num2 (add1 num)
(displayln num2))
How can I do this in racket?
Update
The reason I would like to use eval or the previous questions is that I am using Z3 racket binding, I need to generate formulas (which uses racket binding APIs), and then I will fire the query at some point, that's when I need to evaluate those code.
I have not figured out other ways to go in my case...
One super simple example is, imagine
(let ([arr (array-alloc 10)])
(array-set! arr 3 4))
I have some model to analyze the constructs (so I am not using racketZ3 directly), during each analyzing point, I will map the data types in the program into the Z3 types, and made some assertions,
I will generate something like:
At allocation site, I will need to make the following formula:
(smt:declare-fun arr_z3 () IntList)
(define len (make-length 10))
Then at the array set site, I will have the following assertions and to check whether the 3 is less then the length
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat)
Then finally, I will gather the formulas generated as above, and wrap them in the form which is able to fire Z3 binding to run the following gathered information as code:
(smt:with-context
(smt:new-context)
(define len (make-length 10))
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat))
This is the super simple example I can think of... making sense?
side note. Z3 Racket binding will crash for some reason on version 5.3.1, but it mostly can work on version 5.2.1
Honestly, I don’t understand what exactly you would like to achieve. To quote N. Holm, Sketchy Scheme, 4.5th edition, p. 108: »The major purpose of quasiquotation is the construction of fixed list structures that contain only a few variable parts«. I don’t think that quasiquotation would be used in a context like you are aiming at.
For a typical context of quasiquotation consider the following example:
(define (square x)
(* x x))
(define sentence
'(The square of))
(define (quasiquotes-unquotes-splicing x)
`(,#sentence ,x is ,(square x)))
(quasiquotes-unquotes-splicing 2)
===> (The square of 2 is 4)
Warning: if you're not familiar with how functions work in Scheme, ignore the answer! Macros are an advanced technique, and you need to understand functions first.
It sounds like you're asking about macros. Here's some code that defines test to be a function that prints 2:
(define-syntax-rule (show-one-more-than num)
(begin
(define num2 (add1 num))
(displayln num2)))
(define (test)
(define num1 1)
(show-one-more-than num1))
Now, I could (and should!) have written show-one-more-than as a function instead of a macro (the code will still work if you change define-syntax-rule to define), but macros do in fact operate by producing code at their call sites. So the above code expands to:
(define (test)
(define num1 1)
(begin
(define num2 (add1 num1))
(displayln num2)))
Without knowing the problem better, it's hard to say what the correct approach to this problem is. A brute force approach, such as the following:
#lang racket
(define (make-test-body lst)
(define source `(define (test)
(define num 1)
(define l (list))
,#lst))
source)
(define lst
`((define num2 (add1 num))
(displayln num2)))
(define test-source
(make-test-body lst))
(define test
(parameterize ([current-namespace (make-base-namespace)])
(eval `(let ()
,test-source
test))))
(test)
may be what you want, but probably not.

How can i overload a function at run time in Scheme?

rt.
I want to redefine a function at run time so that i can change the behavior of the system at run time.
thanks.
(define (foo x) ...stuff...)
(set! foo (lambda (x) ...different stuff...))
It might be advisable to use let to do this locally, this can also apply to keywords in this sense:
(let ((define +))
(define 2 3)) ; ===> 5
Or even redefine them to constants, remember, Scheme is a lisp-1:
(let ((define 2) (+ 4))
(- define +)) ; ===> -2
Or even:
(let ((quote /))
'3) ===> 1/3
Doing it only locally preserves the functional style.
Assuming you want to overload a function you defined earlier, simply define it again. This also works for redefining functions such as car and cdr, e.g. to make car into cdr:
(define (car x) (cdr x))
However, I think you won't be able to affect other already defined functions with such a redefinition, so a system function which uses car will still use the original system car and not yours:
(define (test x) (car x))
(define (car x) (cdr x))
(test '(1 2 3))
1
I guess the reason for this is that internally the symbols disappear once a function gets read or evaluated and the symbols are replaced by what they're bound to; in this case, the actual code of the function. So rebinding a symbol to a different function won't affect the rest of your already defined code. This is usually a good thing because it helps uphold referential transparency.
If you want to redefine scheme keywords such as lambda or cond, use let-syntax (see http://community.schemewiki.org/?scheme-faq-language)

Resources