[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