jsn
2018-5-9 12:37:34

@jsn has joined the channel


jsn
2018-5-9 12:40:28

hi there. Is this a proper place for raising potential bugs?


abmclin
2018-5-9 13:10:59

I believe it’s fine to discuss here any issues you have.


abmclin
2018-5-9 13:11:07

@jsn


jsn
2018-5-9 13:13:56

the following fails in the second test only. I wouldnt believe that copying should be dependant on the struct-options (#:transparent) ?! #lang racket/base (require rackunit) (struct Mystruct1 (x y) #:transparent) (struct Mystruct2 (x y)) (define (mycopy1 x) (struct-copy Mystruct1 x)) (define (mycopy2 x) (struct-copy Mystruct2 x)) (define X1 (Mystruct1 1 2)) (define X2 (Mystruct2 1 2)) (module+ test (check-equal? X1 (mycopy1 X1)) (check-equal? X2 (mycopy2 X2))) ;;<- fail here.

. FAILURE name: check-equal? location: struct-bug.rkt:16:2 actual: #<Mystruct2> expected: #<Mystruct2>


abmclin
2018-5-9 13:19:15

Yes, the #:transparent option does make a difference.


jsn
2018-5-9 13:20:52

is it a bug or a feature?


abmclin
2018-5-9 13:21:01

The last paragraph on this page https://docs.racket-lang.org/reference/structures.html?q=struct clarifies that structs are only equal if their types are the same, fields are not opaque, and result of struct-&gt;vector are the same. In your case, Mystruct2 instances fields are opaque


abmclin
2018-5-9 13:21:21

well it’s by design, though I don’t know why it’s designed that way.


jsn
2018-5-9 13:30:56

yes, quite strange. I have a Very-Large-Struct so I decided to have it not #:transparent so I wouldnt print it by accident..


pnwamk
2018-5-9 13:31:26

you can customize printing regardless of whether or not a struct is opaque



abmclin
2018-5-9 13:32:05

well as far as I can gather, the idea is to control how structs can be “inspectable” equal? works by default if struct is #:transparent otherwise you can provide your own equality by using the gen:equal+hash generic interface


abmclin
2018-5-9 13:32:34

for opaque structs or to override the default #:transparent equality


pnwamk
2018-5-9 13:32:46

my simple understanding: an opaque struct can act as an arbitrary abstraction / a transparent struct exposes much more of its internal structure to anyone who can get their hands on it


pnwamk
2018-5-9 13:33:28

I believe there have been comments that #:transparent may have been a better default (instead of opaque) when declaring a struct (could be wrong or there may have been more to it)


pnwamk
2018-5-9 13:33:59

but that comment was a “hind-sight” comment if I recall


abmclin
2018-5-9 13:34:32

yes I have come across archived discussions about how in retrospect #:transparent was the right default behavior, oh well. We have to live with past design choices.


abmclin
2018-5-9 13:36:17

struct is used heavily in the Racket ecosystem, in the infrastructure implementations so it has accumulated a lot of add-ons and behaviors that seem inexplicable to typical application programmers. I only have used the basic struct features, haven’t had the need to use the more obscure features.


jsn
2018-5-9 14:05:04

thanks @abmclin @pnwamk I will try and see if I can work around this using gen:equal+hash The point here was not so much the printing of the struct it self, it was more not being able to compare ‘like’ to ‘like’ when the struct is not #:transparent.


joslarki
2018-5-9 16:37:31

@joslarki has joined the channel


ben
2018-5-9 18:13:11

is or/c associative for “good” contracts? i.e. is (or/c A B C) the same as (or/c A (or/c B C)) and (or/c A (or/c B (or/c C))) ….


ben
2018-5-9 18:13:31

(by “good” I’m thinking “no state”)


samth
2018-5-9 18:14:22

@robby would know for sure, but i would worry about flat vs ho contracts


robby
2018-5-9 23:06:26

@ben I think it is associative regardless of the good or badness of A, B, and C. (Assuming they evaluate to contracts, and you are not doing any especially weird things in combinatory you write outside the contract system).


ben
2018-5-10 00:00:44

hm, I found an example where adding an inner or/c can lead to an exception — because it delays a flat contract that would pass: &gt; (define ctc0 (or/c (-&gt; boolean?) procedure? (-&gt; string?))) &gt; (define ctc1 (or/c (-&gt; boolean?) (or/c procedure? (-&gt; string?)))) &gt; (contract ctc0 void 'pos 'neg) #&lt;procedure:void&gt; &gt; (contract ctc1 void 'pos 'neg) ; readline-input:4:0: broke its own contract ; two of the clauses in the or/c might both match: (-&gt; boolean?) and (or/c ; procedure? (-&gt; string?))


ben
2018-5-10 00:01:33

(but so far, no reason typed racket shouldn’t flatten nested or/cs in the contracts it makes)


dan
2018-5-10 00:20:18

@ben @robby I don’t understand why it’s ok to apply ctc0 to void there, don’t the first order checks of the 2 -> contracts overlap?


robby
2018-5-10 00:21:48

Yes I agree with Dan


robby
2018-5-10 00:21:51

Looks buggy


robby
2018-5-10 00:22:07

Oh I know why


robby
2018-5-10 00:22:34

I have the wrong answer upthread.


robby
2018-5-10 00:23:03

It isn’t associative unless all of the flat contracts come first (or they are all flat or none are)


dan
2018-5-10 00:27:03

@robby shouldn’t the first example above error also though? I thought or/c applied the first order checks to disambiguate the higher order contracts? or is it that it short circuits if a flat contract would succeed first?


ben
2018-5-10 00:27:19

I can still get an error if all the flat contracts come first &gt; (define ctc0 (or/c procedure? (-&gt; boolean?) (-&gt; string?))) &gt; (define ctc1 (or/c (or/c procedure? (-&gt; boolean?)) (-&gt; string?))) &gt; (contract ctc0 void 'pos 'neg) #&lt;procedure:void&gt; &gt; (contract ctc1 void 'pos 'neg) ; readline-input:4:0: broke its own contract ; two of the clauses in the or/c might both match: (or/c procedure? (-&gt; ; boolean?)) and (-&gt; string?)


ben
2018-5-10 00:27:45

@dan I’m using or/c to “change the answer” of contract-first-order


robby
2018-5-10 00:27:51

Or/c first collects all flat ones and then checks them. Only if they fail to pass does it look at the ho ones.


robby
2018-5-10 00:28:12

I see what you mean, Ben, so my wording was bad.


dan
2018-5-10 00:28:46

@robby ok, that makes sense and now I understand why ctc0 is successfully applied in both of @ben’s examples


ben
2018-5-10 00:28:47

I guess, it’s associative if it doesn’t group a flat contract with a chaperone?


robby
2018-5-10 00:28:59

Something like that


robby
2018-5-10 00:29:24

Maybe or/c is the wrong combinator for TR


robby
2018-5-10 00:29:37

Maybe it should use something less “clever”


ben
2018-5-10 00:30:09

maybe, but I think I can turn this into a useful simplification rule for now


ben
2018-5-10 00:30:30

if there’s a nested or/c and all its members are flat, then it can definitely be un-nested


robby
2018-5-10 00:31:43

Yes


robby
2018-5-10 00:32:01

There may be more general rules too


robby
2018-5-10 00:32:19

In the case above it seems surprising that TR would generate such a contract


ben
2018-5-10 00:32:32

yeah, definitely