Zulip Chat Archive

Stream: new members

Topic: Are these two styles completely equivalent?


Dan Abramov (Sep 11 2025 at 17:17):

  have hfn :  {i},  s : S i, f s n' = i := by
    intro i s
    -- ...

vs

  have hfn {i} (s : S i) : f s n' = i := by
    -- ...

Is there any differences between these at all from the outside perspective? Or are they 100% equivalent?

Aaron Liu (Sep 11 2025 at 17:18):

in all normal cases these do the exact same thing

Aaron Liu (Sep 11 2025 at 17:20):

I can think of one case where I think these will be different

Dan Abramov (Sep 11 2025 at 17:25):

From the typesystem's perspective, this is the same type, right? Just different way to format it. Although then I'm not sure how to interpret the fact that ∀ {i}, ∀ s : S i, f s n' = i is also a legit independent thing (of type Prop). Whereas I'm not sure if I can rip out some version of {i} (s : S i) : f s n' = i as a standalone expression, and what type it could have...

Jakub Nowak (Sep 11 2025 at 17:25):

Does hfn (s := smth) works with the first one?

Dan Abramov (Sep 11 2025 at 17:27):

Jakub Nowak said:

Does hfn (s := smth) works with the first one?

Yup, works with both.

Yakov Pechersky (Sep 11 2025 at 17:27):

The former requires an intro tactic step to introduce the variables. You might not want that if the step is to apply a recursor.

Ruben Van de Velde (Sep 11 2025 at 17:29):

The second is just syntax for the former, just like theorem fn {i} (s : S i) : f s n' = i := sorry is syntax for theorem fn : \forall...

Dan Abramov (Sep 11 2025 at 17:32):

Ruben Van de Velde said:

The second is just syntax for the former

In my mind, theorem itself is syntax sugar for something like noncomputable def; wouldn't this mean that normal argument lists in def are also syntax sugar for ? I guess I was expecting currying to be the primary primitive.

Lawrence Wu (llllvvuu) (Sep 11 2025 at 17:49):

IIUC noncomputable def can be used to define data, even if the data is uncomputable, but theorem can’t be used to define data at all

Aaron Liu (Sep 11 2025 at 18:07):

tada

set_option pp.proofs true
set_option pp.mvars false

/--
trace: case h
u n' : Nat
S : Nat → Type
f : {i : Nat} → S i → Nat → Nat
kc : (i : Nat) → (s : S i) → (n : Nat) → f s n = i → Nat
ss : S u
⊢ kc u ss n'
      (have hfn := fun {i} => ?_;
      hfn ss) =
    0

case c
u n' : Nat
S : Nat → Type
f : {i : Nat} → S i → Nat → Nat
kc : (i : Nat) → (s : S i) → (n : Nat) → f s n = i → Nat
ss : S u
⊢ ∀ (i : Nat) (s : S i), f s n' = i
---
warning: declaration uses 'sorry'
-/
#guard_msgs in
example (u n' : Nat) (S : Nat  Type) (f : {i : Nat}  S i  Nat  Nat)
    (kc : (i : Nat)  (s : S i)  (n : Nat)  f s n = i  Nat)
    (ss : S u) :
    ( i (s : S i), f s n' = i)   hn, kc u ss n' hn = 0 := by
  refine ⟨?c, ?n, ?h
  rotate_left
  have hfn :  {i},  s : S i, f s n' = i := by
    intro i s
    exact ?c i s
  exact hfn ss
  trace_state
  all_goals sorry

/--
trace: case h
u n' : Nat
S : Nat → Type
f : {i : Nat} → S i → Nat → Nat
kc : (i : Nat) → (s : S i) → (n : Nat) → f s n = i → Nat
ss : S u
⊢ kc u ss n'
      (have hfn := fun {i} s => ?_;
      hfn ss) =
    0

case c
u n' : Nat
S : Nat → Type
f : {i : Nat} → S i → Nat → Nat
kc : (i : Nat) → (s : S i) → (n : Nat) → f s n = i → Nat
ss : S u
⊢ ∀ (i : Nat) (s : S i), f s n' = i
---
warning: declaration uses 'sorry'
-/
#guard_msgs in
example (u n' : Nat) (S : Nat  Type) (f : {i : Nat}  S i  Nat  Nat)
    (kc : (i : Nat)  (s : S i)  (n : Nat)  f s n = i  Nat)
    (ss : S u) :
    ( i (s : S i), f s n' = i)   hn, kc u ss n' hn = 0 := by
  refine ⟨?c, ?n, ?h
  rotate_left
  have hfn {i} (s : S i) : f s n' = i := by
    exact ?c i s
  exact hfn ss
  trace_state
  all_goals sorry

Aaron Liu (Sep 11 2025 at 18:07):

yeah it's really not a very big difference


Last updated: Dec 20 2025 at 21:32 UTC