Zulip Chat Archive

Stream: std4

Topic: Bug in extended binders?


Kyle Miller (Jun 24 2023 at 22:07):

The expression ∀ x, ∀ x < x, True currently expands to ∀ (x : ?m) (x_1 : ?m), x_1 < x_1 → True rather than ∀ (x : ?m) (x_1 : ?m), x_1 < x → True. This seems like a bug to me, since you'd expect the < x to be sort of like a type ascription (and that's what a student at the MSRI summer school expected; they had another example using \in that seemed like it ought to work, but I forgot exactly what it was). Alpha renaming lets you work around it easily at least.

I imagine a fix would be to be careful with macro scopes, but it seems like it'd make the | `(∀ $x:ident $pred:binderPred, $p) => `(∀ $x:ident, satisfies_binder_pred% $x $pred → $p) macro rule much more complicated.

Kevin Buzzard (Jun 24 2023 at 22:28):

I would regard the expression as garbage. Do we really want to work around people using x to mean two different things in the same sentence?

Kyle Miller (Jun 24 2023 at 22:37):

You're not wrong, but it's good to have a solid interpretation of even unreasonable things. You don't want the meaning to change drastically just because of some shadowing.

Kyle Miller (Jun 24 2023 at 22:45):

The example I saw was closer to \forall n, ..., \forall n \in f n, ..., which is less nonsensical than seeing x < x, and on first glance whatever it was seemed fine.

Mario Carneiro (Jun 24 2023 at 23:15):

I don't think it can be done with macro scopes alone. When you write ∀ x, ∀ x < x, True, all occurrences of x there have exactly the same hygiene

Mario Carneiro (Jun 24 2023 at 23:16):

it is rather the elaborator that does the resolution of names to particular fvars and which is affected by name shadowing

Mario Carneiro (Jun 24 2023 at 23:17):

If the inner x was being introduced by the macro then we could fix this with hygiene (or rather, it would behave as you would like already), but here both x's are being specified by the user so there is no way to hygiene them separately

Mario Carneiro (Jun 24 2023 at 23:19):

What might work is

| `( $x:ident $pred:binderPred, $p) => `( $x:ident, satisfies_binder_pred% $x (clear% $x; $pred)  $p)

Kyle Miller (Jun 25 2023 at 00:44):

Ah right that seems like it could work, or something like letI p := fun x => satisfies_binder_pred% x $pred; ∀ $x:ident, beta% p $x → $p, where beta% would be this


Last updated: Dec 20 2023 at 11:08 UTC