As the title implies, I don't understand the difference between using #:transparent and using #:prefab when defining a struct. The reference mentions that prefab involves some sort of global sharing.
What is the difference between them? In which situation should I use one over the other?
To make a structure type transparent, use the #:transparent keyword after the field-name sequence:
(struct posn (x y)
#:transparent)
> (posn 1 2)
(posn 1 2)
An instance of a transparent structure type prints like a call to the constructor, so that it shows the structures field values. A transparent structure type also allows reflective operations, such as struct? and struct-info, to be used on its instances.
Although a transparent structure type prints in a way that shows its content, the printed form of the structure cannot be used in an expression to get the structure back, unlike the printed form of a number, string, symbol, or list.
A prefab (“previously fabricated”) structure type is a built-in type that is known to the Racket printer and expression reader. Infinitely many such types exist, and they are indexed by name, field count, supertype, and other such details. The printed form of a prefab structure is similar to a vector, but it starts #s instead of just #, and the first element in the printed form is the prefab structure type’s name.
Lastly, I think you may need using #:transparent most of the time over #:prefab ,based on my experience I usually use #:transparent.
To extend the other answers and give some more examples for the second part of the question:
#lang racket
(struct A (x y))
(displayln (A 1 2)) ; => #<A>
(equal? (A 1 2) (A 1 2)) ; => #f
;(equal? (A 1 2) (read (open-input-string (~a (A 1 2))))) ; => ERR: bad syntax
(struct B (x y) #:transparent)
(displayln (B 3 4)) ; => #(struct:B 3 4)
(equal? (B 3 4) (B 3 4)) ; => #t
(equal? (B 3 4) (read (open-input-string (~a (B 3 4))))) ; => #f
(struct C (x y) #:prefab)
(displayln (C 5 6)) ; => #s(C 5 6)
(equal? (C 5 6) (C 5 6)) ; => #t
(equal? (C 5 6) (read (open-input-string (~a (C 5 6))))) ; => #t
Use opaque structs if you want to enforce the struct abstraction with no exceptions, i.e., the struct can only be created and inspected with the accessors.
Use transparent structs to give access to the printer and equal?.
Use prefab structs if you want to do serialization, e.g. when writing and reading from disk.
The racket guide probably has a more gentle introduction to prefab structs.
The biggest difference is that a transparent struct still requires the struct constructor to create one of them.
For example, given the following struct definition:
(struct foo (a b) #:prefab)
The following are two ways to create the exact same struct.
> (foo 1 2)
'#s(foo 1 2)
> #s(foo 1 2)
'#s(foo 1 2)
This means that any racket module can create a foo prefab struct, even without it being defined first. This makes it very useful if you want to put it in a macro, or send it to a separate instance of racket running on a different machine.
Generally, I would recommend going with #:transparent structs unless you need the full power of a #:prefab struct.
One other important detail not mentioned yet: transparent (and normal) structs are generative. This means if you define the same struct twice, values created with the first instance of the struct definition are not equal? to values created with the second definition. You can see this for yourself in a REPL session:
> (struct posn (x y) #:transparent)
> (define origin1 (posn 0 0))
> (struct posn (x y) #:transparent)
> (define origin2 (posn 0 0))
> (equal? origin1 origin2)
#f
Despite being the same definition and having the same content, the two instances are not equal?. Although the structs are transparent they are considered separate definitions for the reason Leif Anderson pointed out, just using #:transparent still requires that the only way to create the struct be with the constructor the struct form defines. Two definitions means two different constructors.
However, with prefab structures, that limitation goes away - you can create prefab structs yourself by just writing the reader form of them like #s(posn 0 0). There's no longer a reason to require all instances of the struct be created with its defined constructor, and thus no reason two different but identical struct definitions wouldn't recognize each other:
> (struct posn (x y) #:prefab)
> (define origin1 (posn 0 0))
> (struct posn (x y) #:prefab)
> (define origin2 (posn 0 0))
> (equal? origin1 origin2)
#t
> (equal? origin1 #s(posn 0 0))
#t
I am of the opinion that structs that represent just some raw data pooled together should be prefab to get free, easy, and safe serialization, structs that have restrictions on how they can be constructed should be transparent, and structs that should encapsulate some behavior and hide information should be neither transparent nor prefab. These are mere guidelines however, your mileage may vary.
Related
To construct the transitive and reflexive closure R *.
The binary relation R = {(1,1), (1,2), (2,1), (2,2), (3,1), (3,4), (4,1), (4,2), (4,4)}
What we can do is turn the data into some graph structure, like an adjacency hash table. Then we can traverse it and back-fill the missing transitive and reflexive relationships.
TXR Lisp program:
;; association data
(defvar rel-pairs '((1 1) (1 2) (2 1) (2 2) (3 1) (3 4) (4 1) (4 2) (4 4)))
;; turn data into hash table associating each domain value
;; with its range values.
(defvar rel [group-reduce (hash) car (op cons (cadr #2) #1) rel-pairs])
(defun ensure-trans-reflex (hash)
;; ensure reflexivity: if [hash key] maps to some values,
;; each of those values should appears as keys mapping
;; back to the key.
(dohash (key values hash)
(each ((val values))
(pushnew key [hash val])))
;; ensure transivity: individually starting at each
;; key in the hash, we recursively traverse the graph,
;; and associate that key with values thus reachable.
(dohash (key values hash hash)
(let ((visited (hash)))
(labels ((transitivize (key value)
(each ((next-val [hash value]))
(when (test-set [visited next-val])
(pushnew next-val [hash key])
(transitivize key next-val)))))
(each ((val values))
(transitivize key val))))))
(prinl rel)
(ensure-trans-reflex rel)
(prinl rel)
Output:
$ txr rel.tl
#H(() (1 (2 1)) (2 (2 1)) (3 (4 1)) (4 (4 2 1)))
#H(() (1 (4 3 2 1)) (2 (3 4 2 1)) (3 (2 3 4 1)) (4 (3 4 2 1)))
Basically, the example data ends up associating every key with every key including itself.
Here is an implementation in Common Lisp which exhibits a problem with a naïve approach to this sort of question.
First of all some definitions.
The kernel of the relation is a map with entries which look like (x . y). R(a, b) if there is an entry in the kernel like (a . b). I am not sure if 'kernel' is the correct mathematical term (I'm pretty sure it's not), but it's what I'm going to use.
The relation R is reflexive if R(a, a) for any a which occurs either in the domain or the range of the relation.
The transitive closure of R, R* is the relation such that R*(a, b if R(a, b) or (R(a, c) and R*(c, b)).
So I'm going to implement the kernel of the map just as a list, and I will explicitly use car, cdr, and cons to extract the parts of entries in the kernel. This is grotty old-fashioned Lisp, but in this case it's pretty much fine, since the natural objects in this part of the language (conses) map very nicely onto the objects in the problem. Note also that I have not tried to use any fancy data structures at all: everything is just walking down lists. This would make the thing slow if the kernel was very large. But it's not very large.
Here is the kernel you are given:
(defparameter *kernel*
'((1 . 1)
(1 . 2)
(2 . 1)
(2 . 2)
(3 . 1)
(3 . 4)
(4 . 1)
(4 . 2)
(4 . 4)))
This kernel is not reflexive: (3 . 3) is missing for instance. Here is a function which, given a kernel, returns a reflexive version of it. This function has very poor complexity, but the kernel is small and the function gets called once.
(defun reflexifize-kernel (kernel)
;; given the kernel of a map, return a reflexive version of it
;; This has pretty grotty complexity but it gets called only once
(loop for element in (loop with d/r = '()
for e in kernel
do (pushnew (car e) d/r)
do (pushnew (cdr e) d/r)
finally (return d/r))
for ik = (cons element element)
unless (member ik kernel :test #'equal)
collect ik into identities
finally (return (append kernel identities))))
And we can check this:
> (reflexifize-kernel *kernel*)
((1 . 1)
(1 . 2)
(2 . 1)
(2 . 2)
(3 . 1)
(3 . 4)
(4 . 1)
(4 . 2)
(4 . 4)
(3 . 3))
You can see it's added the appropriate entry at the end (and it would have added more entries if it needed to).
Now I'll write a function which, given the left-hand-side of a mapping and a kernel returns two things:
the first match for this left-hand-side in the kernel, or nil if there is none;
the remainder of the kernel after this match, or () if there is one (note that nil and () are the same in Common Lisp, but they might not be in other Lisps).
The nice thing here is that we can just use the remainder of the kernel to look for more matches, and this function works really nicely with the implementation of the kernel above: this is a case where Lisp's data structures really work well for us.
(defun next-match (lhs kernel)
;; return the next match (as (lhs . rhs)) for lhs in kernel, and the
;; remainder of the kernel, or nil and () if there is no match
(let ((found (member lhs kernel :key #'car)))
(if found
(values (first found) (rest found))
(values nil '()))))
So, now we can write a function, Rp which is true if R(a, b) is true:
(defun Rp (lhs rhs kernel)
;; is R(lhs, rhs) true
(multiple-value-bind (entry remaining-kernel) (next-match lhs kernel)
(cond ((null entry)
nil)
((eql (cdr entry) rhs)
t)
(t (Rp lhs rhs remaining-kernel)))))
This is called Rp because it's a predicate (ending in p in the usual Lisp convention), and it tells us if two elements satisfy R. And of course since CL is case-insensitive by default, this is the same function as rp.
And this function works fine:
> (rp 1 1 (reflexifize-kernel *kernel*))
t
> (rp 1 3 (reflexifize-kernel *kernel*))
nil
And now we can write R*p: it's clearer, I think and certainly more efficient to write a 'unified' version of R*p which does not rely on Rp, but is very similar code with it: it's really just got a final step which searches for the transitive closure.
(defun R*p (lhs rhs kernel)
;; is lhs related to rhs in kernel? (See note below!)
(multiple-value-bind (entry remaining-kernel) (next-match lhs kernel)
(if (null entry)
nil
(let ((match-rhs (cdr entry)))
(if (eql rhs match-rhs)
t
(or (R*p lhs rhs remaining-kernel)
(R*p match-rhs rhs kernel)))))))
OK, so this looks obviously correct, right?
first we look for a match for lhs;
if there's a match, and its rhs is rhs then we're done;
if there isn't then
first search for more matches in the kernel and check them
if that fails look for matches for the rhs we found whose rhs is rhs.
And this is just transparently the definition of the transitive closure, right? So if we feed it a reflexive kernel (which we can create now), it will work.
Well, no, it won't work. It won't work because there are loops in the kernel you've been given. Let's say we want to call (R*p 1 3 (reflexivize-kernel *kernel*)). It's obvious from the kernel that this should be false.
But in fact the function fails to terminate. It fails to terminate because it finds there's an entry for R(1, 2) and so it starts looking for R*(2, 3): it then finds R(2, 1), starts looking for R*(1, 3) ... oops.
(Note that the implementation above does depth-first search. Breadth-first search doesn't help: it will help find a mapping when there is one but when there isn't it will just loop in the same way.)
The way to deal with this is to use what's called an occurs check: when searching we keep track of the things we have already looked at up the search tree. If we find we're looking at a lhs which we have already looked at we fail immediately, as this is a loop. Here is an implementation of a version of R*p which does that, using a local function so we don't need to provide the so-far list in the interface, whichh would be annoying.
(defun R*p (lhs rhs kernel)
;; is lhs related to rhs in kernel, with an occurs check.
(labels ((R*p-loop (lhs rhs kernel so-far)
(if (member lhs so-far)
;; we've looped, give up
nil
(multiple-value-bind (entry remaining-kernel)
(next-match lhs kernel)
(if (null entry)
nil
(let ((match-rhs (cdr entry)))
(if (eql rhs match-rhs)
t
(or (R*p-loop lhs rhs remaining-kernel so-far)
(R*p-loop match-rhs rhs kernel
(cons lhs so-far))))))))))
(R*p-loop lhs rhs kernel '())))
And this version works:
> (R*p 1 3 (reflexifize-kernel *kernel*))
nil
> (R*p 1 1 (reflexifize-kernel *kernel*))
t
> (R*p 1 2 (reflexifize-kernel *kernel*))
t
> (R*p 2 1 (reflexifize-kernel *kernel*))
t
> (R*p 2 3 (reflexifize-kernel *kernel*))
nil
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 ().
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.
I was asked in an internship interview to do a R5RS program that creates a function, let's say two-subsets. This function has to return #t if the list L contains two subsets with equal sums of elements and with equal numbers of elements, otherwise it returns #f. It takes in entry the list L (only positive numbers) and some parameters (that I judge useful. There is no conditions on the number of parameters) all equal to 0 at the beginning.
The requirements as I still remember were as follow:
- Do not define other functions and call them inside the "two-subsets" function.
- It can only use the following constructs: null?, cond, car, cdr, else, + ,=, not, and, #t, #f, two-subsets (itself for recursive call), the names of the parameters, such as list, sum, ...etc, numeric constants and parentheses.
There were some given examples on the results that we are supposed to have, let's say:
(two-subsets '(7 7) 0 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(7 7 1) 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(5 3 2 4) 0 0) returns #t. The two subsets are {2, 5} and {3, 4}.
(two-subsets '(1 2 3 6 9) 0 0) returns #f.
I started by writing the signature that it looks to me it should be something like this:
(define two-subsets (lambda (L m n ... other parameters)
(cond
The problem is really complicated and it's complexity is obviously more than O(n), I read on it on https://en.wikipedia.org/wiki/Partition_problem .
I tried to start by defining the algorithm first before coding it. I thought about taking as parameters: sum of the list L so in my conditions I'll iterate only on the combinations which sum is <= sum(L)/2. By doing that I can reduce a little bit the complexity of the problem, but still I couldn't figure out how to do it.
It looks like an interesting problem and I really want to know more about it.
Here is a version which does not depend on the numbers being all positive. I am reasonably sure that, by knowing they are, you can do much better than this.
Note this assumes that:
the partition does not need to be exhaustive;
but the sets must not be empty.
I'd be very interested to see a version which relies on the elements of the list being +ve!
(define (two-subsets? l sl sld ssd)
;; l is the list we want to partition
;; sl is how many elements we have eaten from it so far
;; sld is the length difference in the partitions
;; ssd is the sum difference in the partitions
(cond [(and (not (= sl 0))
(= sld 0)
(= ssd 0))
;; we have eaten some elements, the differences are zero
;; we are done.
#t]
[(null? l)
;; out of l, failed
#f]
;; this is where I am sure we could be clever about the set containing
;; only positive numbers, but I am too lazy to think
[(two-subsets? (cdr l)
(+ sl 1)
(+ sld 1)
(+ ssd (car l)))
;; the left-hand set worked
#t]
[(two-subsets? (cdr l)
(+ sl 1)
(- sld 1)
(- ssd (car l)))
;; the right-hand set worked
#t]
[else
;; finally drop the first element of l and try the others
(two-subsets? (cdr l) sl sld ssd)]))
I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative number. My question is: can I convert it somehow to a valid pointer? My attempts to use cffi:convert-from-foreign and cffi:translate-from-foreign (what's the difference between them anyway?) failed.
Below is my actual (not working) code:
(defun put-pixel (pixbuf x y r g b)
(let ((p (+ (gdk:pixbuf-get-pixels pixbuf) (* x (gdk:pixbuf-get-n-channels pixbuf)) (* y (gdk:pixbuf-get-rowstride pixbuf)))))
(setf (cffi:mem-aref p :unsigned-char 0) r)
(setf (cffi:mem-aref p :unsigned-char 1) g)
(setf (cffi:mem-aref p :unsigned-char 2) b)))
CFFI:TRANSLATE-FROM-FOREIGN is a generic function. You can define your own foreign types using CFFI:DEFINE-FOREIGN-TYPE and then add a method to CFFI:TRANSLATE-FROM-FOREIGN to specify how the conversions from foreign to Lisp values should work.
CFFI:CONVERT-FROM-FOREIGN is what you should call if you need to explicitly convert some value. It will call CFFI:TRANSLATE-FROM-FOREIGN behind the scenes and it might perform some compile-time optimizations if possible.
Same thing applies to CFFI:CONVERT-TO-FOREIGN and CFFI:TRANSLATE-TO-FOREIGN.
I think that lambda-gtk incorrectly defined binding for pixbuf-get-pixels.
The negative value for pointer value might appear because of incorrect interpretation of unsigned integer as a signed integer.
The simplest way to correct this value is to use mod:
CL-USER> (mod -1 (expt 2 #+cffi-features:x86 32 #+cffi-features:x86-64 64))
4294967295