contact
2018-11-1 09:58:45

Thank you for the cool 7.1 release! Specially: > (define (add #:x x #:y y) (+ x y)) > (define add1 (curry add #:x 1)) > (add1 #:y 2) 3 Really neat! Thx!


contact
2018-11-1 10:21:08

Is there a way to declare package dependencies so that something like raco install would install all the necessary dependencies? Like Anaconda environments.


samth
2018-11-1 12:20:37

@contact yes, you declare dependencies in the info.rkt file


contact
2018-11-1 12:20:57

Great thx!


samth
2018-11-1 12:23:13

I think you’d have to ask @robby or maybe @dan


robby
2018-11-1 12:52:59

It affects contract-blame


robby
2018-11-1 12:53:27

If you are making a combinator, you can use it to stick blame onto something so that contract-blame will return it. It is on you (as the combinator author) to get that right.


abmclin
2018-11-1 13:23:16

@contact if you want to avoid manually specifying dependencies, raco setup has an option to automatically detect missing dependencies and write them to the correct package’s info.rkt file.

There’s a concise tutorial that has useful details http://blog.racket-lang.org/2017/10/tutorial-creating-a-package.html


contact
2018-11-1 13:24:56

Great! Will take a look. Thx!


notjack
2018-11-1 15:43:15

I don’t see a contract-blame function in the docs


vibhavp
2018-11-1 17:18:49

@vibhavp has joined the channel


vibhavp
2018-11-1 17:20:56

Hello, is the Racket VM’s bytecode instruction set documented anywhere?


robby
2018-11-1 17:38:28

Oops, object-blame


robby
2018-11-1 17:38:40

Uhhh value-blame?


robby
2018-11-1 17:39:29

It answers only the question “who might get blamed if I use this value”. There are no other guarantees


dan
2018-11-1 17:39:30

I think value-blame queries it. I had thought value-blame might be used in the contract-profiler, but I’m not sure about that.

I don’t think it changes the error messages anywhere, and it’s just a convenient place to store the blame information on a contracted value in case some tool needs to use that information


notjack
2018-11-1 17:45:41

Are there tools that use it? Why would a tool want to use it?


macocio
2018-11-1 19:22:23

@macocio has joined the channel


lexi.lambda
2018-11-1 20:05:10

@robby In the test suite for the contract system, is there a contract I can use if I want to test that something works with a (conjoin contract? (negate chaperone-contract?))? Testing against any of the built-in contracts that happen to currently produce non-chaperone contracts (such as, for example, class contracts) seems like a bad idea, since they could always be improved to produce chaperone contracts in the future.


robby
2018-11-1 20:05:52

An impersonator contract?


lexi.lambda
2018-11-1 20:06:39

Right. I’m wondering if there’s a canonical impersonator contract that is guaranteed to not become a chaperone contract at some point in the future.


dan
2018-11-1 20:09:03

@lexi.lambda you can just write your own with make-contract unless I’m misunderstanding?


samth
2018-11-1 20:09:29

parametric/c generates impersonator contracts that have to be that way


lexi.lambda
2018-11-1 20:09:43

@dan Yes, I can do that if that’s the right answer, I was just wondering if there was something else the test suite did something else by convention.


lexi.lambda
2018-11-1 20:09:58

@samth That’s a good point!


lexi.lambda
2018-11-1 20:14:06

I don’t think I can really use parametric contracts here, though, since I’m putting a contract on an immutable data structure, which doesn’t really have a meaningful way to use parametric contracts… though I guess I could write a function on the immutable data structure, instead.


lexi.lambda
2018-11-1 20:19:45

(Also, I only just noticed impersonator-contract? exists; I find it a little weird that flat-contract? appears to imply chaperone-contract? but impersonator-contract? is its own thing.)


dan
2018-11-1 20:50:55

@lexi.lambda I’ve had issues with these distinctions before too because I think there are at least two reasonable views: 1. There’s a hierarchy and all flat contracts are also chaperones, and all chaperone contracts are impersonators, but some impersonators are neither flat nor chaperone 2. The categories are disjoint, so flat is distinct from chaperone which must wrap and preserve behavior bs impersonators with no guarantees.

I think the predicates that recognize these things have ended up somewhere in the middle of these two so it’s sort of confusing, although I think impersonator-contract? is roughly equivalent to not flat and not chaperone


lexi.lambda
2018-11-1 20:52:08

There’s also the additional point of confusion that chaperone-contract? recognizes contracts whose projections must produce values that satisfy chaperone-of?, but impersonator-contract? projections do not have to preserve impersonator-of?.


paul
2018-11-1 22:18:58

I have discovered something that must point to a misunderstanding on my part. The first function behaves as I’d expect. What’s going on with the second function?

    (if (or (not x) (equal? y 'surprise))
        'invalid
        y))
> (check #t 'surprise)
'invalid
    (parametric->/c [X] (boolean? X . -> . X))
    (if (or (not x) (equal? y 'surprise))
        'invalid
        y))
> (check #t 'surprise)
'surprise

macocio
2018-11-1 22:35:15

paul
2018-11-2 01:01:44

@macocio Yes, I read the description. I don’t have a good grip on wrappers yet. But is the mere presence of a contract supposed to change the evaluation of the if form? Why does (check #t 'surprise) evaluate differently with the contract?


greg
2018-11-2 01:02:19

@paul Speaking of 'surprises and equal?: The doc for equal? mentions it works for “inspectable structures”. Well, Racket structs are by default opaque — not inspectable. Only #:transparent (or #:prefab) structs can be equal?. This sometimes catches people by surprise (where “people” includes me in the past, and other people I’ve talked to.)


macocio
2018-11-2 01:04:23

@paul because (equal? 'surprise #<X>) => #f, so it returns y


notjack
2018-11-2 01:08:31

@paul The mere presence of a chaperone or flat contract is not supposed to change semantics in ways like that. However, impersonator contracts can pretty much do whatever they want. Most contracts are flat or chaperone. As far as I know, parametric contracts are the only use case for impersonator contracts.


notjack
2018-11-2 01:09:17

So a good rule of thumb is that as long as you’re not using parametric contracts, you won’t run into impersonators and contracts won’t change how equal? works


paul
2018-11-2 01:22:44

Wow! I must do more reading on contracts. So does this mean that the following documentation ought to be reworked not to use equal?? Or should a sentence or two be added to explain what is going on? It sure fooled me.

https://docs.racket-lang.org/reference/parametric-contracts.html?q=parametric-%3Ec#%28form._%28%28lib._racket%2Fcontract%2Fparametric..rkt%29._parametric-~3e%2Fc%29%29


notjack
2018-11-2 01:33:04

I think what the docs were trying to explain with that example is that parametric-> is supposed to change how equal? works, because a parametric function isn’t supposed to do anything with the inputs its parametric in. This includes inspecting them with equal?.


notjack
2018-11-2 01:34:09

It’s a bit weird that the docs for parametric->/c have an example of how not to use it without first presenting an example of how you’re supposed to use it correctly.


macocio
2018-11-2 01:35:40

it should probably be (X . -> . (listof X)) to indicate that the focus is on the types, not the code within… that parametric types aren’t supposed to be “used” by the function since it lacks type information.


macocio
2018-11-2 01:35:55

ofc change the fn appropriately to fit that contract


notjack
2018-11-2 01:36:18

If you’re looking to improve those docs, I’d fix that. After the current two paragraphs of prose add an example of a good use of parametricity like this:

 (define/contract (choose-one bool a b)
    (parametric->/c [X] (boolean? X X . -> . X))
    (if bool a b))

notjack
2018-11-2 01:37:16

I don’t think talking about it in terms of types will be helpful; parametric contracts have some very big differences from a parametrically polymorphic type variable


macocio
2018-11-2 01:39:23

@notjack I like that example, I’d also like to show readers how to use them in type constructors (define/contract (cons-same x lst) (parametric->/c [X] (X (listof X) . -> . (listof X)) (cons x lst))


notjack
2018-11-2 01:39:30

The way parametric contracts work is if a function promises that it doesn’t care what input it’s given, the parametric contract says “okay prove it” by wrapping every input as it goes into the function so all the function sees is this black box value that it can’t do anything with. It’s deliberately not equal? to any other value.


macocio
2018-11-2 01:40:19

I say type ctors but it’s probably called something different in racket. This is maybe useful for more haskell-oriented people I guess


notjack
2018-11-2 01:40:48

If a function says it doesn’t care about its input, but then actually tries to peek at the input by testing it with equal? or do something else with it (like log it), the opaque wrapper causes that to fail


paul
2018-11-2 01:42:35

Then I have to say that the example in the documentation now, without any explanation, feels like a deliberate trap. Where can I read about these wrappers that explains what y’all have just explained to me?

I’m not sure I’m ready to update the documentation. Should I add an issue and then hopefully come back to it in the future and deal with it myself?


notjack
2018-11-2 01:42:58

I think an issue would be great


notjack
2018-11-2 01:43:39

Hmm. There’s a section in the racket guide on parametric contracts: https://docs.racket-lang.org/guide/contracts-exists.html


notjack
2018-11-2 01:43:47

but it’s not linked from the reference section


notjack
2018-11-2 01:43:53

and it doesn’t cover parametric->/c


notjack
2018-11-2 01:45:51

I think the only place this is thoroughly discussed is the paper on parametric contracts


macocio
2018-11-2 01:46:28

For debugging purposes, can we extract information out of the opaque object?


notjack
2018-11-2 01:51:00

ah hah! found the paper



notjack
2018-11-2 01:52:18

wait nope


notjack
2018-11-2 01:54:31

notjack
2018-11-2 01:59:36

Okay I found the paper I was thinking of. It’s “Relationally-Parametric Polymorphic Contracts”: https://www.eecs.northwestern.edu/~robby/pubs/papers/dls2007-gmfk.pdf


notjack
2018-11-2 02:17:15

> “Informally, if a function f accepts an argument of type α, parametricity ensures that the argument is abstract to f — the argument may not be examined or deconstructed by f in any way. Moreover, f may not determine the concrete type of α. This seemingly harsh restriction in fact allows rich abstractions. Since values of type α are abstract to f, a programmer may change the concrete type of α and be assured that the behavior of f will not change. Therefore, we want contracts of the form (forall (α ...) C) to preserve the static notion of parametric polymorphism at runtime. Such contracts will implement—that is to say, detect violations of—relational parametricity.”

@paul Does this prose help?


notjack
2018-11-2 02:18:01

@macocio I don’t think so. If you try to log it it just prints as something like #<opaque>