pigpigyyy / Yuescript

A Moonscript dialect compiles to Lua.
http://yuescript.org
MIT License
450 stars 39 forks source link

Abstract classes and interfaces support? #57

Open CriztianiX opened 3 years ago

CriztianiX commented 3 years ago

Trying to make more solid OOP, what do you think about to add abstract classes and interfaces? The checking can be done at compilation time throwing an error maybe.

pigpigyyy commented 3 years ago

It's a good idea. Since interfaces are like some kinds of type info, we might need to implement the static typed system to support these features and get the work done after #15.

CriztianiX commented 3 years ago

Maybe, the #15 is not necessary at all. i think something like PHP/Ruby etc.

Here some examples for interfaces. We need 2 new reserved words. interface and implements

interface Repository
  all: ()
  read: (id)
class UserRepository implements Repository
  all: () =>
  read(id) =>
class BookRepository implements Repository
  all: () =>

In this examples, compilation for BookRepository should be fail due to missing methods

For abstract classes can be something like:

abstract class User
  abstract role: ()

  hello: => ´hello #{@role!}´
class AdminUser extends User
  role: => 'Admin'
class EditorUser extends User
user = User!
gytis-ivaskevicius commented 3 years ago

Typesystem implementation will end up with some sort of interface or interface-like feature. Abstract Classes - in OOP inheritance it is already strongly discouraged due to lack of flexibility. Not sure why one would encourage it here.

If one were to take a look - Many if not most OOP languages/codebases are adapting ideas/concepts of FP, maybe yuescript should take such ideology as well.

Sod-Almighty commented 2 years ago

Abstract Classes - in OOP inheritance it is already strongly discouraged due to lack of flexibility

Then does Yuescript support mixins? That is, the ability to "include" arbitrary snippets of code into a class?¹

In my opinion, this is a much better solution than traditional OOP. For instance, it avoids the massive clusterfudge of multiple inheritance.


¹ Languages that support this include Ruby and Rust.

pigpigyyy commented 2 years ago

Yes, there is a syntax sugar for mixing. You can use it with

class A using B, C

and get

local A -- 1
do -- 1
  local _class_0 -- 1
  local _base_0 = { } -- 1
  local _list_0 = { -- 1
    B, -- 1
    C -- 1
  } -- 1
  for _index_0 = 1, #_list_0 do -- 1
    local _mixin_0 = _list_0[_index_0] -- 1
    for _key_0, _val_0 in pairs(_mixin_0.__base) do -- 1
      if not _key_0:match("^__") then -- 1
        _base_0[_key_0] = _val_0 -- 1
      end -- 1
    end -- 1
  end -- 1
...