Mark, watch this

Community Forums/Monkey2 Talk/Mark, watch this

JoshKlint(Posted 2015) [#1]
Already posted, but worth pointing out:
http://www.youtube.com/watch?v=5kj5ApnhPAE

This guy describes my feelings on languages perfectly.


marksibly(Posted 2015) [#2]
Yeah, I like that talk a lot!

I 'sort of' like the idea of getting rid of 'implements', eg:

interface ILight
   method Color:Color()
   method Range:Float()
end

class Light
   method Color:Color()
      ...blah
   end
   method Range:Float()
      ...blah
   end
end

function Main()
   local light:ILight=new Light    'no problemo!
end


I suspect that'll upset some Java users! But I think it's a 'safe' thing to be able to do, and reduces noise significantly.

On the down side, it isn't as obvious whether or not a class implements an interface, but is that a big deal?


Danilo(Posted 2015) [#3]
marksibly wrote:
On the down side, it isn't as obvious whether or not a class implements an interface, but is that a big deal?

It's absolutely horrible. When reading the class code, you don't see that it conforms to an Interface (but you should see this already).
You have to search all files for IClassName to know if there is something going on behind the scene, or not.


therevills(Posted 2015) [#4]
It's absolutely horrible.

I agree, you can not see at a glance what contracts it needs to fulfil.

Its similar to what I don't like about C# interfaces, you cant tell by just looking at the code if you are using an interface or extending a class:
C#:
class Foo : Bar

Is Bar an interface or the superclass!?!?!

Java:
class Foo implements Bar

I know that Bar is an interface...


Danilo(Posted 2015) [#5]
- Interfaces in Go


JoshKlint(Posted 2015) [#6]
The point is not the details of Go, but the idea of a niche between C++/Java and script languages.


nullterm(Posted 2015) [#7]
On the down side, it isn't as obvious whether or not a class implements an interface, but is that a big deal?


IMO, I think ya need to keep Implements ILight, more so for human eyes looking and understanding. I get that the code is smaller/simpler, and that's generally a good/great thing. But seeing "Implements ILight" instantly tells me that I can plug it into another object that talks to ILight's.


Samah(Posted 2015) [#8]
@marksibly: On the down side, it isn't as obvious whether or not a class implements an interface, but is that a big deal?

I can't believe you're even asking that question...

@Danilo: It's absolutely horrible.

Completely agree.

@nullterm: But seeing "Implements ILight" instantly tells me that I can plug it into another object that talks to ILight's

Exactly.


ziggy(Posted 2015) [#9]
The idea of making interface implementations not obvious does not make interfaces understanding any easier and I suspect code that does infer interfaces usage can be harder to maintain. If I modify an interface, suddenly I'll need to evaluate all classes that where implementing it, to identify which ones do not now, and if I miss any one, the code will fail at runtime. Having explicit implementations will make it a lot easier to identify class implementations, and will allow for this situations where the interface has been modified to be detected at compile time, which makes maintenance a lot better!

So, while I agree that language needs to be expressive and compact, and be as easy to follow as possible, it should not come to the cost of making it expensier to maintain or to understand. Knowing which classes implement an interface in code, is a design information that should not be hidden by inference.


marksibly(Posted 2015) [#10]
> if I miss any one, the code will fail at runtime.

No, it'd still fail at compile time - if an object doesn't have the required methods, it can't be used in place of an interface. Edit the interface and you still have to edit implementing classes.


Danilo(Posted 2015) [#11]
@JoshKlint:
I just wondered where did Mark get the idea that keywords should be removed now, and it looks like
it came from the video, or maybe by looking at GoLang Interfaces (but Go works differently).

The question is, do ILight and Light automatically work together in Mark's idea? And if ILight and Light
are automatically bundled together, how would this work with classes that implement 2, 3 or 4 Interfaces?

Or was the idea taken from GoLang?

GoLang simply reverses many things. Where MX1 users say "Class C conforms to Interfaces X,Y,Z", GoLang users write "Class C"
and the GoLang compiler automatically detects that the type "Class C" conforms to Interfaces X,Y,Z (if they are defined).

interface IAnyInterface
   method Color:Color()
   method Range:Float()
end

class Light
   method Color:Color()
      ...blah
   end
   method Range:Float()
      ...blah
   end
end

GoLang automatically detects that Light implements/conforms to IAnyInterface.
If you remove method Color() from the class, it would not conform to IAnyInterface anymore,
and if you add a new method "Length()", it detects that class Light now also confirms to IAnotherInterface.

While the compiler can detect that automatically, I think it's different for the programmer. Given 3 classes C,D,E
the programmer needs to search similarities between the 3 classes to know what Interfaces it conforms to.
And then, if he found similarities, he could write:
local c:ISomeInterface = new C
local d:ISomeInterface = new D
local e:ISomeInterface = new E

I think this completely reverses the meaning of Interfaces as used now
(contracts/warranty that the developer implements certain methods)


marksibly(Posted 2015) [#12]
> Or was the idea taken from GoLang?

The idea was taken from the Go video posted at the top. I thought the idea of the compiler pretty much 'auto-writing' all the 'Implements' stuff for you was interesting and worth exploring a bit.

> I think this completely reverses the meaning of Interfaces as used now

Not really, I think what it does is reduce 'implements' to the documentation level, ie: if you want to know what a class implements, you read the docs. Classes still have to implement the correct interface methods if they want to be able to be used in place of interfaces, so it's not 'weaker', and the same programs would compile or not compile.

Rust takes interfaces in an even more interesting direction:

interface Drawable
   method Draw:void( x:float,y:float )
end

class Circle
   field radius:float
end

implement Drawable for Circle
   method Draw:void( x:float,y:float )
      DrawCircle( x,y,radius )
   end
end


(or something like that...)


ziggy(Posted 2015) [#13]
Rust takes interfaces in an even more interesting direction
I found it to be particulary horrendous (sorry). Having class methods defined and implemented outside the class feels somehow wrong to me. Maybe it's just me, but I like seeing a class source code and having an idea of what the class actually does without having to look what the class could also be doing, because it's defined somewhere else.

Interfaces defined outside the class look like enforced addapter code to me. Enforcing design patterns like this is a bit going too far if you ask me.


Gerry Quinn(Posted 2015) [#14]
"Implements ILight" may be strictly speaking just enforced documentation, but it's a ton of essential programmer documentation for the price of only two words (and you already had to type far more than two words to implement the interface methods). I'm pretty sure that there are better ways to make a language using Basic syntax more concise, if that is even an ambition!

Like Ziggy, I like to be able to go to where a class is defined and see quickly what it is and what it does.


Danilo(Posted 2015) [#15]
Self-documenting code is nice. The code itself is the documentation, and HTML etc. can easily be generated from it, including catching all "implements".

What if you have 5 Interfaces with method Draw(x,y)? For example imported from different libraries.
Circle will then automatically confirm to all 5 interfaces?
If you write a class with 10 methods, the compiler automatically chooses - out of some hundred or thousands of available interfaces -
to what interfaces my class confirms to?
With "implements" I tell the compiler what I want to do, and if I forget to implement a certain method, the compiler tells me so.
Without telling the compiler about the agreement, it would shift the error message to the first attempt to use a certain method or interface somewhere.


marksibly(Posted 2015) [#16]
> Having class methods defined and implemented outside the class feels somehow wrong to me.

Same here, but aren't you curious why they've done it this way? What would its strengths be? There are already calls for 'class Image Extension' and this definitely is in line with that!

> I like seeing a class source code and having an idea of what the class actually does without having to look what the class could also be doing, because it's defined somewhere else.

Yes, but a class can't do everything on it's own, unless it's a butt ugly mega class. This idea definitely has the appeal to me of being able to write lightweight classes that can be used in very flexible ways, ie: ANY class can be made 'Drawable' very easily. Rect and Circle might be in a geom module somewhere. What's the 'correct' alternative to this? It'd involve wrappers/containment/extension or some other extra 'layer' of crud.

I'm not about to actually implement any of these ideas, but I can definitely see some benefits to both of them.


marksibly(Posted 2015) [#17]
> Circle will then automatically confirm to all 5 interfaces?

Yep, and I like that! I think it'd result in far more code being written that used interfaces.

> If you write a class with 10 methods, the compiler automatically chooses - out of some hundred or thousands of available interfaces - to what interfaces my class confirms to?

The compiler only has to worry about the interfaces you try and use a class with. If you never convert a class C to an interface I, the compiler never has to check if C implements I.

> Without telling the compiler about the agreement, it would shift the error message to the first attempt to use a certain method or interface somewhere.

Errors would occur at exactly the same point, ie: when you tried to convert a class to an interface.

As you say, you lose some 'self documentation'. But it's kind of interesting to consider that that's all implements is - compulsory documentation/form filling. It doesn't really have to be there.


Samah(Posted 2015) [#18]
So what about IDEs with automatic refactoring? If I want to change a method name in the interface, I need to manually find each and every class that implements it.


Danilo(Posted 2015) [#19]
marksibly wrote:
Errors would occur at exactly the same point, ie: when you tried to convert a class to an interface.

As you say, you lose some 'self documentation'. But it's kind of interesting to consider that that's all implements is - compulsory documentation/form filling. It doesn't really have to be there.

I see your point:
Strict

Interface Computer
    Method Boot:Void()
    Method Process:Void()
    Method Display:Void()
End

Class PC Implements Computer
    Method Boot:Void()
        Print "PC.Boot()"
    End
    Method Process:Void()
        Print "PC.Process()"
    End
    Method dusplay:Void()
        Print "PC.Display()"
    End
End

Function Main:Int()
    Local pc:= New PC  ' compiles, even if the class is incorrect / incomplete
                       ' (class does not conform to the interface, violating the promise)

    pc.Boot()          ' works
    pc.Process()       ' works

    'pc.Display()       ' Error : Identifier 'Display' not found.
    
    Return 0
End

I expected the compiler to be more strict and helpful catching errors/mistakes/typos.

Can't this be dangerous, if you give such an incorrect / incomplete class instance to an external function/method (C++ for example),
or something like that?

EDIT: OK, the compiler begins to complain when using the Interface somewhere outside.
Strict

Interface Computer
    Method Boot:Void()
    Method Process:Void()
    Method Display:Void()
End

Class PC Implements Computer
    Method Boot:Void()
        Print "PC.Boot()"
    End
    Method Process:Void()
        Print "PC.Process()"
    End
    Method dusplay:Void()
        Print "PC.Display()"
    End
End

Function Main:Int()
    f(New PC())
    Return 0
End

Function f:Void(c:Computer)
    c.Boot()
    c.Process()
    c.Display()
End



ziggy(Posted 2015) [#20]
Yes, but a class can't do everything on it's own, unless it's a butt ugly mega class. This idea definitely has the appeal to me of being able to write lightweight classes that can be used in very flexible ways, ie: ANY class can be made 'Drawable' very easily. Rect and Circle might be in a geom module somewhere.
You say flexible, I read single responsibility being sort of erased. Extension methods are a bit like this, that's true too. I'm not saying it's a bad idea, just I'm afraid it could make it easier to embrace non SOLID design, but maybe it's just me being sort of too strict or something


Pharmhaus(Posted 2015) [#21]
If you like to remove unnecessary code then taking a look at how Scala handles things could maybe help you.
It is always astonishing to me how easy it is to write things when the language is well designed and not bloated.
Java 8 has changed a little but it still can't compete with dialects like scala in my opinion.
It also does concurrent programming well (enough), many modern langauges really suck at this (*cough*).


dmaz(Posted 2015) [#22]
Having class methods defined and implemented outside the class feels somehow wrong to me.
I haven't finished the thread yet but I had to comment here. I totally disagree. I think go and rust and to a lesser extent obj c (which I dislike the syntax) and all the others are right. Composition [edit] is a huge benefit to class design.. I whole heartily think it should be implemented.

edit:
and I like rust's syntax better than go's.


dmaz(Posted 2015) [#23]
I should clarify that they do this for composition... and it should not replace inheritance


dmaz(Posted 2015) [#24]
I'm not about to actually implement any of these ideas
boo :)


ziggy(Posted 2015) [#25]
I haven't finished the thread yet but I had to comment here. I totally disagree. I think go and rust and to a lesser extent obj c (which I dislike the syntax) and all the others are right. Composition [edit] is a huge benefit to class design.. I whole heartily think it should be implemented.
That makes SOLID design more complex and easy to break.
I could "buy it" if it was defined to provide interface mapping to actual class defined methods. That would make sense, as a quick interface adapter. But if interface "mapping" AND functiona implementation is defined outside the class, the whole thing seems a lot less robust to me.


Skn3(Posted 2015) [#26]
While on subject of interfaces... Can we have default method implementation for interfaces? So one can implement the interface in a class, but pick and choose which methods they override. Basically multiple inheritance?

With regards to the interface switcheroo being suggested... Agh looks fugly. I'm sure it would be something you get used to, but it sure doesn't feel comfortable to think about. The rust style suggested does seem quite good though, however what advantage does it have really? I am probably not thinking hard about it enough...


Shinkiro1(Posted 2015) [#27]
I like how Mark questions what others take as given in a programming language.
The feeling that something looks wrong/feels wrong is NOT a good indicator over how useful that feature could be.
Speaking for myself, before I learned OO and later Interfaces both concepts looked alien to me in the beginning and I constantly questioned if there was any value to it.


The rust style suggested does seem quite good though, however what advantage does it have really?


You can basically extend any class (even other peoples) to fit them in your code. All that while leaving the code/files of others untouched. You simply build on top of it.


Skn3(Posted 2015) [#28]
You can basically extend any class (even other peoples) to fit them in your code. All that while leaving the code/files of others untouched. You simply build on top of it.


Oh I see, yeah that could be awesome... Being able to tack interfaced methods onto other classes I could definitely get behind!


Samah(Posted 2015) [#29]
If this is going to be supported, I don't think you can really call them interfaces any more as they no longer provide a solid contract. I can't immediately find all the classes that could be "coerced" to that data type.
Interfaces should be implemented exactly as they are in Monkey X, but the functionality suggested in this thread (if added to the language) should be given a new term. I see no reason why these two functionalities can't exist side-by-side.


taumel(Posted 2015) [#30]
+1 for interfaces like Mark mentioned them.


Nobuyuki(Posted 2015) [#31]
(I'm still in the process of reading the thread as I write this.....)

Making the compiler a bit more dynamic when using interfaces seems like a neat idea (especially if it works like Go), but the problem comes when/if you start hitting limitations of this feature that people don't/won't expect, particularly 1. new coders, 2. coders experienced in languages that don't have this feature (ie: they're familiar with interfaces but unfamiliar with how they're implemented in mx2), and 3. Users of languages like Go where mx2's implementation of Interfaces isn't as "auto-magical" as the language they're familiar with; or at the very least, isn't as "auto-magical" in the same way.

Getting this wrong could end up earning the feature a bad reputation, even if the idea itself has useful benefit. Compare the Variant type which some BASICs of the past had to say, Python / Ruby's dynamic typing....