[Grace-core] Aside from Abstract

Kim Bruce kim at cs.pomona.edu
Tue Nov 5 22:49:44 PST 2013


That could work.  How would we restrict what items could go into a variant type if EmptyList is just an object?  Is it sufficient that it just have a match method?  That could be reasonable (e.g. with Number), but I worry somebody might forget to wrap the value with singleton and end up with a weird match that doesn't correspond to our interpretation of this as a type (not just a pattern).

Kim



On Nov 5, 2013, at 6:17 PM, James Noble <kjx at ecs.vuw.ac.nz> wrote:

>> 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