Thinkin' about what we need to make modules work
5 files changed, 40 insertions(+), 32 deletions(-)

M tests/programs/test_module2.gt
M tests/programs/test_module3.gt
M tests/programs/test_module6.gt
M tests/programs/test_module7.gt
M tests/programs/test_module5.gt => tests/programs/test_monad.gt
M tests/programs/test_module2.gt +4 -1
@@ 8,11 8,14 @@ 
 -- Dummy type
 type String = I32
 
--- TODO: Mangle "Self" since it's a keyword in Rust
+-- TODO: Make the compiler mangle "Self" since it's a keyword in Rust
+-- Also "self" and "impl"
 type Show(@Selff) = struct
     show: fn(@Selff) String
 end
 
+-- To make this work we need monomorphization, 'cause Rust refuses to
+-- call a function pointer in a const function
 const IntShow Show(I32) = Show {
     .show = fn(x I32) String = String(x) end
 }

          
M tests/programs/test_module3.gt +19 -19
@@ 6,8 6,8 @@ 
 
 -- Fine let's try something simpler.
 
-type Eq(@Self) = struct
-    eq: fn(@Self, @Self) Bool,
+type Eq(@Selff) = struct
+    eq: fn(@Selff, @Selff) Bool,
 end
 
 -- The name here has to be something other than Eq(I32) 'cause we

          
@@ 17,25 17,25 @@ end
 -- To ponder: What if we did attach names to types, or had
 -- specialization?  The latter evokes the Instance Problem, the former
 -- I suppose is a way around it.
-const IntEq Eq = Eq {
+const IntEq Eq(I32) = Eq {
     .eq = fn(lhs I32, rhs I32) Bool =
         true
     end,
 }
 
-type Ord(@Self) = struct
-    cmp: fn(@Self, @Self) I32,
+type Ord(@Selff) = struct
+    cmp: fn(@Selff, @Selff) I32,
 end
 
-const IntOrd Ord = Ord {
+const IntOrd Ord(I32) = Ord {
     .cmp = fn(lhs I32, rhs I32) I32 =
         0
     end,
 }
 
 
-type From(@Self, @In) = struct
-    from: fn(@In) @Self
+type From(@Selff, @In) = struct
+    from: fn(@In) @Selff
 end
 
 const BoolFromInt From(Bool, I32) = From {

          
@@ 47,21 47,21 @@ type List(@T) = struct
 end
 
 
-type Idx(@Self, @Output) = struct
-    idx: fn(@Self, I32) @Output,
+type Idx(@Selff, @Output) = struct
+    idx: fn(@Selff, I32) @Output,
 end
 
-type Len(@Self) = struct
-    len: fn(@Self) I32,
+type Len(@Selff) = struct
+    len: fn(@Selff) I32,
 end
 
 const ListLen Len(List(@T)) = Len {
-    .len = fn(self List(@T)) I32 = 0 end
+    .len = fn(selff List(@T)) I32 = 0 end
 }
 
-fn module_len(impl Len(@T), l @T) I32 =
+fn module_len(impll Len(@T), l @T) I32 =
     let total I32 = 0
-    impl$.len(l)
+    impll$.len(l)
 end
 
 -- Specialize it just to make sure everything fits together...

          
@@ 69,8 69,8 @@ fn list_len(l List(@T)) I32 =
     module_len(ListLen, l)
 end
 
-const ListIdx Idx(List(@T)) = Idx {
-    .idx = fn(self List(@T), i I32) @T = self$.dummy_data end
+const ListIdx Idx(List(@T), @T) = Idx {
+    .idx = fn(selff List(@T), i I32) @T = selff$.dummy_data end
 }
 
 -- Generalized thingy...

          
@@ 80,8 80,8 @@ fn idx(l List(@T)) @T =
 end
 
 -- Can we make another instance for a more specialized type?
-const IntListIdx Idx(List(I32)) = Idx {
-    .idx = fn(self List(I32), i I32) I32 = self$.dummy_data end
+const IntListIdx Idx(List(I32), I32) = Idx {
+    .idx = fn(selff List(I32), i I32) I32 = selff$.dummy_data end
 }
 
 fn main() {} =

          
M tests/programs/test_module6.gt +0 -3
@@ 4,9 4,6 @@ 
 -- Run:
 --   stdout: 3
 
--- TODO: BUGGO: This test occasionally fails to pass, *hopefully*
--- because of HashMap ordering shenanigans.  Investigate.
-
 -- A generic functional map from a key to a value
 type Map(@T, @K, @V) = struct
     get: fn(@T, @K) @V,

          
M tests/programs/test_module7.gt +16 -8
@@ 7,6 7,8 @@ 
 /- Another monad-ish attempt, this also gets called map
 From modular implicits paper section 3.4
 
+To make this work we need closures that capture their scope properly.
+
 module type Functor = sig
   type + 'a t
   val map : ('a -> 'b) -> 'a t -> 'b t

          
@@ 23,24 25,30 @@ type Cell(@V) = struct
 end
 
 fn make_cell_functor(f fn(@A) @B) Functor(Cell(@A), Cell(@B)) =
-    Functor {
-        .map = fn(cell Cell(@A)) Cell(@B) =
-            Cell {
-                .val = f(cell$.val)
-            }
-        end
-    }
+    let m = fn(c Cell(@A)) Cell(@B) =
+        Cell({
+            .val = f(c$.val)
+        })
+    end
+    Functor({
+        .map = m,
+    })
 end
 
+/-
 fn f(i Bool) I32 =
     12
 end
+-/
 
 fn main() {} =
-    let test_cell = Cell {
+    {}
+    /-
+    let test_cell Cell(Bool) = Cell {
         .val = true
     }
     let thing = make_cell_functor(f)
     let test_result Cell(I32) = thing$.map(test_cell)
     __println(test_result$.val)
+    -/
 end

          
M tests/programs/test_module5.gt => tests/programs/test_monad.gt +1 -1
@@ 42,7 42,7 @@ end
 -- The good news is, we don't seem to be able to implement real monads
 -- I think if we had associated types?
 type Monad(@A, @M) = struct
-   return: fn(@A) @M(@A),
+   return_: fn(@A) @M(@A),
    bind: fn(@M(@A), fn(@A) @M(@B)) @M(@B)
 end