
@hoshom You could also define qty
as a generic interface.

Oh. You’re right

For a generic interface, let’s say qty
, how do I make a contract, that says: (-> qty? qty-constructor instance-of-qty-constructor)
As opposed to: (-> qty? (-> n qty?) qty?)
(which says the return value must implement the qty
interface, but doesn’t say anything about its type)


Another way of phrasing the contract I want to make: (-> some-struct-value?
struct-type-that-implements-generic-interface?
struct-instance-of-that-type?)

Almost got it… if qty
is a generic interface name, and kg
is a struct that implements it, then struct-type-that-implements-generic-interface?
corresponds to (generic-instance/c gen:qty (get-qty (-> qty? number?)))
and the matching value will be struct:kg
, not kg
But then what corresponds to struct-instance-of-that-type?

Sounds to me like the answer is to use a macro to obtain the struct-info, which will contain a predicate and a constructor, in the function body, use the constructor, and in the contract, the range will be something that matches the predicate. Is that correct? Of course, this doesn’t need a contract, it’s trivial to see that if I pass in the constructor and create the value using that constructor the returned value will be correct. But it helps with understanding this stuff.

Generally, it’s best just to refer to the generic interface contract (qty?
) and not try to be more specific. The value of the generic interface is that it allows you to ignore the details of the particular type that you’re using.

Is there an easy way to convince scribble to render an @itemlist
using a., b., c., instead of 1., 2., 3.?

ah, nvm, I’ll work around it another way

what i get from struct-auto-info-lists
https://docs.racket-lang.org/reference/structinfo.html#%28def._%28%28lib._racket%2Fstruct-info..rkt%29._struct-auto-info-lists%29%29\|[link] is that should only give accessors and mutators identifiers from fields with #:auto
, yet i have this. (begin
(struct a-struct (a [b #:mutable] [c #:auto] [d #:auto #:mutable]))
(define-syntax (from-id-get-auto-info stx)
(syntax-parse stx
[(_ name:id)
#`'#,(struct-auto-info-lists (syntax-local-value #'name))]))
(from-id-get-auto-info a-struct))
> '((a-struct-c a-struct-d) (set-a-struct-b! set-a-struct-d!))
Is this a bug? set-a-struct-b!
should not be there?

@cris2000.espinoza677: yeah, it’s a bug

If you want to help fixing it, here’s where you should take a look https://github.com/racket/racket/blob/master/racket/collects/racket/private/define-struct.rkt#L749

huh… I tried… the idea is that you can’t trust auto-count
because it was count for the full fields
list which sets
has been filtered from. in L596 a new variable is needed, one that counts how many fields were accumulated until an auto field is detected using field-auto?
(also the error handling of #:auto
is above that line so there will be no other cases to handle). and then use that new-count instead of (- (length sets) auto-count)
.
I have the code done, i tried testing it in my installation of racket but it doesn’t seem to take effect? so i cant test it


This expression computes the mutators in the extract-struct-info
. It probably should be lifted up so that it can be reused.

Also, there’s some design decision to make. Should the return value of struct-auto-info-lists
be a (list/c (listof identifier?) (listof identifier?))
or (list/c (listof identifier?) (listof (or/c #f identifier?)))

hum i see is not straightforward


im not gonna pull request because it regresses, since i edited my racket installation which is 7.8

ill see it tomorrow, is like 2am here

Oh, you know what. I think returning (list/c (listof identifier?) (listof identifier?))
makes sense

There’s no need to pad the list with #f
, since people can already compare the mutator against the mutator list from (extract-struct-info ...)

It’s likely you might need to build Racket from source and recompile Racket, since define-struct.rkt
is pretty low-level.