kcl-lang / kcl

KCL Programming Language (CNCF Sandbox Project). https://kcl-lang.io
https://kcl-lang.io
Apache License 2.0
1.61k stars 113 forks source link

Implicit interfaces #1405

Closed steeling closed 3 months ago

steeling commented 3 months ago

Implicit interfaces, similar to go's interfaces would be helpful. Consider the following:

schema MySchema:
   id: str = crypto.uuid()
   name: str
   ....

schema MySchema2:
  id: str
  displayName: str
  ....

interface Obj:
   id: str

collectIDs = lambda objs: [Obj] {
    ret = [v.id for v in objs]
}

collectIDs([MySchema2{...}])

could also reuse the schema keyword and some some matching of sub/supersets.

This would be useful for creating more generic functions.

Peefy commented 3 months ago

I see. But I think inheritance can be used

import crypto

schema Obj:
   id: str

schema MySchema1(Obj):
    id = crypto.uuid()
    name: str

schema MySchema2(Obj):
    displayName: str

collectIDs = lambda objs: [Obj] {
    ret = [v.id for v in objs]
}

res1 = collectIDs([MySchema1 {name = ""}])
res2 = collectIDs([MySchema2 {id = "id", displayName = ""}])

I understand duck types like Go and Typescript, which can be assigned values as long as they have a partial order relationship rather than an explicit declaration. KCL considered this feature at the beginning of its design, but still adopts strict type inheritance and checking for types defined using the schema keyword, because in the schema, besides attributes, other logic can be defined. In addition, KCL also has the protocol keyword, which is a more stringent type of schema that only allows attributes to be defined within it. Perhaps this semantics can be extended.

schema ASchema:
    id: str
    name: str

protocol ASchemaProtocol:
    id: str

a: ASchemaProtocol = ASchema {....}
steeling commented 3 months ago

oh nice, yes this works great, thanks!