> I recently hacked together a little GUI thingy for showing > enumerations that just let them scroll by inside what looks like the > normal enumeration print out and it works by sampling and caching the > first 200 elements of the enumeration, but being careful about errors > and to staying the user's side of the world during the cache > population. It does evaluate things at the point displaying is > happening, but people generally do not have much expectation about > when those functions are evaluated, so it seems to work well as long > as errors that happen are printed sanely.
This sounds neat, although I'm not entirely sure I understand it properly. Do you have this somewhere I could take a look at? > I'm not completely sure I'm getting the point, but is this something > that and/c would need to cooperate with? Like for it to recognize that > sequence? (which maybe should be called sequence/c instead?) is itself > and and/c and print nested ones better? > > Robby Let me explain: the sequence? predicate is simply the predicate generated by define-generics, so it recognizes all things that are sequences. This includes everything that implements gen:sequence as well as all the defaults. This can be a little confusing, though, when it comes to mutable vectors or mutable hash tables. In the #:defaults clause, the predicate for recognizing vectors and hash tables are (conjoin vector? immutable?) and (conjoin hash? immutable?). This is the behavior I want, but it also means that trying to perform a sequence operation on a mutable vector gives a confusing error message. -> (take 2 (vector 1 2 3 4)) ; take: contract violation ; expected: sequence? ; given: '#(1 2 3 4) ; in: the 2nd argument of ; (-> ; exact-nonnegative-integer? ; sequence? ; sequence?) In that error message, it's entirely unclear what's wrong, especially since mutable vectors print the same way as immutable vectors. I want the actual behavior of sequence? to remain identical, but I'd like to improve the error reporting in these cases to help avoid confusion. This is the error message I've come up with. -> (take 2 (vector 1 2 3 4)) ; take: contract violation ; expected: (and/c immutable? sequence?) ; given: '#(1 2 3 4), which is mutable ; in: the 2nd argument of ; (-> ; exact-nonnegative-integer? ; sequence? ; sequence?) Perhaps that printout is misleading. The contract is not actually (and/c immutable? sequence?), it's just sequence?. Maybe it should say "expected: sequence?, which must be immutable". Either way, this is an improvement over the opaque error reporting of the unmodified case. I've implemented this contract like so: (define sequence?* (make-flat-contract #:name 'sequence? #:first-order sequence? #:projection (λ (blame) (λ (val) (cond [(sequence? val) val] [(disjoin vector? hash?) ; raise a custom blame error ] [else ; raise the usual blame error ]))))) I've then provided sequence?* as sequence? via rename-out. However, and/c only uses the first-order check, which is still just plain sequence?, so contract errors where sequence? is used within a combinator are just as opaque as before. -> (first (vector 1 2 3 4)) ; first: contract violation ; expected: (and/c sequence? (not/c empty?)) ; given: '#(1 2 3 4) ; which isn't: sequence? ; in: the 1st argument of ; (-> (and/c sequence? (not/c empty?)) any) I'm not sure what the best solution to this problem is. Perhaps providing some extra information to and/c would be the right approach? Sorry for the long-winded explanation, I just need to make it clear that sequence? is really just a plain old predicate, but I've tacked a custom projection onto it for nicer blame errors. Alexis -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.