gracelang / language

Design of the Grace language and its libraries
GNU General Public License v2.0
6 stars 1 forks source link

Names for Block types #119

Closed KimBruce closed 5 years ago

KimBruce commented 7 years ago

The documentation for the standard prelude introduces the names Block0, Block1, and Block2 for the types of anonymous functions. Java 8 has added similar types for anonymous functions, but calls them names like Function<T,R> and Predicate. I find those names more intuitive and suggestive of their meaning than ours. Might we be better off using notation more similar to theirs?

[I understand anyone can rename them to anything they like, but ...]

apblack commented 7 years ago
type Function0⟦ResultType⟧ = interface { apply -> ResultType }
type Function1⟦ArgType1, ResultType⟧  interface { apply(a1: ArgType1) -> ResultType }
...

Also,

type Procedure0 = Function0⟦Done⟧
type Procedure1⟦A1⟧ = Function1⟦A1, Done⟧
....
apblack commented 7 years ago

Here is a concrete proposal. For what we have been calling Block0, Block1, etc.

type Function0⟦ResultT⟧  = interface {
    apply -> ResultT     \\ Function with no arguments and a result of type ResultT
    matches -> Boolean   \\ answers true
}
type Function1⟦ArgT1, ResultT⟧ = interface {
    apply(a1:ArgT1) -> ResultT    \\ Function with argument a1 of type ArgT1, and a result of type ResultT
    matches(a1:Object) -> Boolean   \\ answers true if a1 <: ArgT1
}
type Function2⟦ArgT1, ArgT2, ResultT⟧ = interface {
    apply(a1:ArgT1, a2:ArgT2) -> ResultT   \\ Function with arguments a1 of type ArgT1, a2 of type ArgT2, and a result of type ResultT
    matches(a1:Object, a2:Object) -> Boolean   \\ answers true if a1 <: ArgT1 and a2 <: ArgT2
}
type Function3⟦ArgT1, ArgT2, Arg3, ResultT⟧  = interface {
    apply(a1:ArgT1, a2:ArgT2, a3:ArgT3) -> ResultT
    matches(a1:Object, a2:Object, a3:Object) -> Boolean   \\ answers true if a1 <: ArgT1 and a2 <: ArgT2 and a3 :< ArgT3
}

For blocks that return no result, i.e., when ResultT is Done

type Procedure0 = Function0⟦Done⟧               \\ Function with no arguments and no result
type Procedure1⟦ArgT1⟧ = Function1⟦ArgT1, Done⟧  \\ Function with 1 argument of type ArgT1, and no result
type Procedure2⟦ArgT1, ArgT2⟧ = Function2⟦ArgT1, ArgT2, Done⟧  
type Procedure3⟦ArgT1, ArgT2, Arg3⟧ = Function3⟦ArgT1, ArgT2, ArgT3, Done⟧

For blocks that return Booleans:

type Predicate0 = Function0⟦Boolean⟧               \\ Function with no arguments returning Boolean
type Predicate1⟦ArgT1⟧ = Function1⟦ArgT1, Boolean⟧  \\ Function with 1 argument of type ArgT1, returning Boolean
type Predicate2⟦ArgT1, ArgT2⟧ = Function2⟦ArgT1, ArgT2, Boolean⟧  
type Predicate3⟦ArgT1, ArgT2, ArgT3⟧ = Function3⟦ArgT1, ArgT2, ArgT3, Boolean⟧

matches is my proposed simplification of the current match protocol, which returns a SuccessfulMatch. It just returns a Boolean. The idea is that match(subject)case(_)… tries to match subject against each of the cases, and when the first returns true, applies the block.

KimBruce commented 7 years ago

The new names are a definite improvement.