lexi.lambda
2017-4-11 16:25:11

@samth: From your help, I managed to implement the variable elimination and constraint generation parts in Haskell to help with my own understanding. The one thing I’m confused about so far is what the σ represents in CG-Fun, which I don’t see mentioned elsewhere.


jerryj
2017-4-11 16:29:33

I guess my main question right now is “How do you debug this stuff”? lol


jerryj
2017-4-11 16:33:06

Does anyone have recommendations for debugging FFI stuff? I assume the answer is something like “read the docs back and forth, do a debug-build of racket and re-learn gdb”.


samth
2017-4-11 16:46:22

lexi.lambda: sigma is a substitution


samth
2017-4-11 16:46:22

reply_broadcast messages not yet supported


lexi.lambda
2017-4-11 16:54:41

Alright… I’m still not clear where it comes from in that particular rule.


samth
2017-4-11 17:02:15

in the App-Inf-Alg rule, \sigma comes from \sigma \in \And C \downarrow R


samth
2017-4-11 17:02:22

the last premise of the rule


samth
2017-4-11 17:03:23

how to compute that is defined on the previous page, where it says “the minimal subsitution \sigma C R can be defined …”


lexi.lambda
2017-4-11 17:05:29

Yes, I see that, but I’m not sure what it means within the CG-Fun rule, since my understanding is that the substitution is computed from the calculated constraints.


samth
2017-4-11 17:07:54

I also don’t know where \sigma is coming from in that rule


samth
2017-4-11 17:08:33

that looks like a typo to me


lexi.lambda
2017-4-11 17:12:20

Hmm. Safe to ignore it, then?


samth
2017-4-11 17:19:24

Yes, I think so


lexi.lambda
2017-4-11 17:19:56

ok, thanks


samth
2017-4-11 17:27:37

Probably there’s some other disjointness condition that should be there, but I couldn’t figure out what it should be


leif
2017-4-11 17:59:36

@jerryj Uhh…do you just mean debugging in general?


leif
2017-4-11 18:00:14

If you can be a bit more precise that would be helpful, otherwise ya, all I got is read the manuals, and squint at your code harder.


jerryj
2017-4-11 19:29:26

@leif I’m having trouble debugging some FFI wrappers I wrote. I’m not getting expected results, it smells like i’m not dereferencing a pointer right or something. I don’t know if there is a reasonable way to poke around in memory after that FFI call to see if i can discover some clues about what I did wrong.


thinkmoore
2017-4-11 19:32:45

i’ve had good success with debug-build of racket + gdb/lldb


jerryj
2017-4-11 19:32:50

Like, I imagine a gdb debug session might look like: 1) breakpoint after the troublesome ffi call, 2) peek at the pointer thats giving me garbage 3) see what that pointer is pointing to to see if it has the correct data / etc. But, that seems very difficult. I am willing to do difficult work, but I am just trying to get a sense if that’s how a real expert would do things


thinkmoore
2017-4-11 19:33:17

minor gotcha is that your ffi libs are loaded dynamically, so you’ll need to use file name + line to set breakpoints, or wait until after the symbols are loaded


thinkmoore
2017-4-11 19:33:59

the underlying scheme object format in memory is relatively simple, but can require a bit of spelunking through header files to figure out


jerryj
2017-4-11 19:35:07

@thinkmoore awesome, thanks!


jerryj
2017-4-11 19:35:59

I’m OK with spelunking, it sounds like i can rely on existing skills to do some of this work. I was worried that I might be getting in way over my head or something.


thinkmoore
2017-4-11 19:38:21

@jerryj there are some gotchas that might trip you up, if for example the problem is racket moving things on you… does your FFI pass racket values back and forth?


jerryj
2017-4-11 19:38:40

yes :grin:



jerryj
2017-4-11 20:12:36

wow it was a lot easier to build racket than I thought it would be. you all are amazing :heart_eyes:


lexi.lambda
2017-4-11 20:16:00

I’m now taking a look at actually generating substitutions from the calculated constraints, and once again, I think I’m getting tripped up over the notation. Section 3.5 states that “for each (S <: X_i <: T) ∈ C”, we can calculate σ_CR(X_i).

I think I understand a few things. R is the return type of the function, and variance can be calculated just by recursively inspecting the type. However, what I don’t understand is the text immediately following that—is it saying that we can prove σ_CR is just σ? What is σ′?


lexi.lambda
2017-4-11 20:19:11

Additionally, the section that describes how σ_CR is calculated describes cases for covariance, contravariance, and invariance, but it also leaves an additional else branch. When might a type be none of those things?


lexi.lambda
2017-4-11 20:20:29

Oh, nevermind that last bit; I missed that it requires invariance and S = T.


samth
2017-4-11 20:23:23

first, σ is the minimal substitution, and we prove that σ_CR is minimal and unique


samth
2017-4-11 20:23:47

second, the last case is sometimes called “bivariant” and it means the variable isn’t referenced at all


lexi.lambda
2017-4-11 20:24:54

Alright, that makes sense. The proofs are pretty much over my head at this point, but I trust that they are correct. ;)


samth
2017-4-11 20:25:27

yeah, you don’t need to pay attention to most of them


samth
2017-4-11 20:25:46

you could always come to OPLSS or the Racket Summer School, though :wink:


lexi.lambda
2017-4-11 20:26:12

Maybe I can figure out how to find the time away from work. ;)


lexi.lambda
2017-4-11 20:26:48

Does this algorithm guarantee that σ_CR(X_i) is unique? That is, I don’t have to worry about producing conflicting substitutions?


samth
2017-4-11 20:28:56

Yes, that’s what the proof proves


lexi.lambda
2017-4-11 20:31:18

ok, I figured as much, but I couldn’t glean that from trying (and failing) to understand it.


lexi.lambda
2017-4-11 21:12:44

hmm… I’ve implemented this, but I may have implemented it wrong. my implementation seems to sometimes generate inconsistent substitutions for ill-typed expressions.


lexi.lambda
2017-4-11 21:14:51

When I try and apply a function of type All(X, Y)(X, X, Y)→X to arguments of type Int, String, and String, it should produce an error, but it happily produces a substitution including both X↦Int and X↦String.


lexi.lambda
2017-4-11 21:16:06

I would imagine the constraint generation part is correct, since it generates the constraints Int <: X <: Top and String <: X <: Top, which seems right.


samth
2017-4-11 21:18:44

you need to combine the two constraint sets together before generating the substitution


samth
2017-4-11 21:18:53

that will fail, giving you your type error


samth
2017-4-11 21:19:42

that’s the big \Wedge in App-Inf-Alg


lexi.lambda
2017-4-11 21:20:42

ah, right, that makes sense. and that can simply use the subtyping relation to determine if the constraints are compatible?


lexi.lambda
2017-4-11 21:21:18

how are type errors produced by that process usually formatted? it seems like the resulting errors could be somewhat confusing.


samth
2017-4-11 21:22:05

C \wedge D is defined at the top of section 3.3


lexi.lambda
2017-4-11 21:22:16

yes, I’m looking at that right now


samth
2017-4-11 21:22:26

well, TR just says it can’t infer the type, and gives you the type of the function and of the arguments


lexi.lambda
2017-4-11 21:23:38

yeah. that seems somewhat worse than unification error messages, though perhaps less likely to produce misleading messages (since it simply doesn’t try to provide anything more precise).


samth
2017-4-11 21:24:21

If you have ideas for including more information, I’d be interested :slightly_smiling_face:


lexi.lambda
2017-4-11 21:25:38

I have no idea :) if that’s the best people have figured out how to do with this inference technique, I doubt I’ll be able to come up with anything better. but I’ll probably start thinking about it once I internalize what’s going on better.


lexi.lambda
2017-4-11 21:26:16

for some reason I think I expected local type inference to be a simpler process than HM, but it seems to be significantly more complicated in practice.


samth
2017-4-11 21:28:01

The actual algorithm W isn’t that simple either


lexi.lambda
2017-4-11 21:29:16

I suppose not, but I’m not sure I’ve ever actually implemented the “real” algorithm W


lexi.lambda
2017-4-11 21:29:58

the simplicity of a single constraint generation pass combined with an extremely straightforward constraint solving pass is pretty easy to understand at a high level, though


samth
2017-4-11 21:30:34

right, the tricky part is (a) when you want to make it efficient and (b) when you add generalization


lexi.lambda
2017-4-11 21:31:10

yeah, I’ve peeked through OutsideIn(X) and it’s terrifying


samth
2017-4-11 21:31:43

I just mean generalization in the let-polymorphism sense


lexi.lambda
2017-4-11 21:32:03

oh, sure. I didn’t realize algorithm w didn’t include that.


lexi.lambda
2017-4-11 21:32:39

though I think I buy the argument against let generalization


lexi.lambda
2017-4-11 21:33:07

I write a lot of haskell with monolocalbinds implicitly enabled and it never really comes up in practice


samth
2017-4-11 21:35:11

no, it does include that


samth
2017-4-11 21:35:19

clearly I’m not communicating well


lexi.lambda
2017-4-11 21:36:02

oh, I see. you’re saying algorithm w is tricky because it does those two things.


jerryj
2017-4-11 22:15:05

Are the Scheme_Type values meant to be human readable? Is there listing somewhere of what types the integer values correspond to?



jerryj
2017-4-11 22:16:01

!! Thanks!


lexi.lambda
2017-4-11 22:44:04

alright, looks like I got my haskell impl working. thanks so much for your help! :)


lexi.lambda
2017-4-11 22:45:46

one remaining question I have… this paper doesn’t mention alpha renaming anywhere. is it something I ever need to worry about? that is, does it assume <:, ∧, and ∨ check for alpha equivalence?