[Grace-core] Aside from Abstract

James Noble kjx at ecs.vuw.ac.nz
Tue Nov 5 18:17:38 PST 2013


> The other thing we decided yesterday beyond having an "abstract" statement to indicate an abstract class is to have a singleton operator.  Singleton takes an identifier defined in a definition and makes it into a type.

So this all makes sense.
I'm sure I had something like this somewhere, but I forgot. 

> def emptyList = object {....}
> 
> type EmptyList = singleton emptyList
> 
> Now EmptyList has the pattern matching semantics expected of a type and can be used in match cases, etc.

I don't think Singleton needs to be an "operator".  Singleton could be a superclass that defines a match method.
(full code below)   

class Singleton.new {
   method match(other) {
       if (self == other) then {return SuccessfulMatch.new(other, [])}
       return FailedMatch.new(other)
   }
}

"value" objects would be singletons - self matching - autozygotic - in precisely this sense. 

> Any object can be used in a match by providing a match method, but that method may not at all conform to the definition expected for a singleton type.  The advantage of singleton is that it provides you automatically with a match method that does exactly what is expected for the singleton type, no matter what the object had (or even if it had no match).

Yep. Alternatively (or additionally) we can make "singleton" as a decorator which works just as you suggest.

method singleton( myself ) {
  object {
      method match(other) {
          if (myself == other) then {return SuccessfulMatch.new(other, [])}
          return FailedMatch.new(other)
   }
  }
}

you'd just have to say

> type EmptyList = singleton(emptyList)



I'm not sure "Singleton" is the right name though - actually I'm sure it's not: https://en.wikipedia.org/wiki/Singleton_pattern

I don't know what a good name. Value? SelfMatch?  Scala calls these "Singleton Types" I know...

code:


print "start"

class Singleton.new {
   method match(other) {
       if (self == other) then {return SuccessfulMatch.new(other, [])}
       return FailedMatch.new(other)
   }
}

def foo = object {
     inherits Singleton.new
}

match (foo) 
    case { (foo) -> print "FOO" }
    case { _ -> print "nonomatch" }
    
    
    
method singleton( myself ) {
  object {
      method match(other) {
          if (myself == other) then {return SuccessfulMatch.new(other, [])}
          return FailedMatch.new(other)
   }
  }
}


def emptyList = object { 
    method size {0}
}

def EmptyList = singleton(emptyList) 

type List = {
    head -> Object
    tail -> List
    size -> Number 
}

class Link.cons(hd,tl) {
    def head is public = hd
    def tail is public = tl
    method size {1 + tail.size}
}

var x : EmptyList | List

x := emptyList
print "{x.size}"

var y : EmptyList | List := Link.cons("A",Link.cons("B",emptyList))
print "{y.size}"


match (x) 
    case { _ : EmptyList -> print "empty" }
    case { l : List -> print "Link: head={l.head}, tail={l.tail}" }
    

match (y) 
    case { _ : EmptyList -> print "empty" }
    case { l : List -> print "Link: head={l.head}, tail={l.tail}" }
  

print "done"






More information about the Grace-core mailing list