Random thoughts and ideas...

Community Forums/Monkey2 Talk/Random thoughts and ideas...

marksibly(Posted 2015) [#1]
Just some weird ideas...

***** Virtual constructors *****

If new() could also be a function, class ctors would be able to return subclasses, eg:

class C
   function new( arg:int )
      if arg=1 return New D
      if arg=2 return new E
      return new C 
   end
end

Class D extends C
end

class E extends C
end


There are issues with this: new may return null (could return null on failure); new may not return unique instances (could return values from a cache). Either could be good or bad...

***** Single line decls/statements ******

Similar to single line If...

function add:int( x:int,y:int ) return x+y

function sum:int( values:int[] )
   local sum:=0
   for local value:=eachin values sum+=value
   return sum
end


Terminating end, wend etc optional.


Samah(Posted 2015) [#2]
Local foo := Closure<String>(a$)
	Print(a)
End

Method Bar(hello:Closure<String>)
	hello("blah")
End

Generic defines the parameter types of the closure.


marksibly(Posted 2015) [#3]
Don't really get that code - what's the point in 'Closure' being generic if all types are known?

Also, I'm not sure if monkey will do 'lambda functions' (same as closures?) just yet, as there are some ugly parsing issues similar to python: http://www.artima.com/weblogs/viewpost.jsp?thread=147358

'Single line' lambdas are possible though.

This code works though:

function Foo<T>:Void( t:T )
    print t
end

function Bar:Void( func:Void(String) )
   func( "blah" )
end

Bar( Foo )



Danilo(Posted 2015) [#4]
marksibly wrote:
function sum:int( values:int[] )
   local sum:=0
   for local value:=eachin values sum+=value
   return sum
end


You could differentiate between single-line and multi-line
by using keywords like 'Then' and 'Do'.

If [expression]
    [statements]
ElseIf [expression]
    [statements]
Else
    [statements]
EndIf

If [expression] Then [statement]

If [expression] Then [statement] Else [statement]

' If you want to allow 'Then' for blocks:
If [expression] Then [end-of-line]
    [statements]
EndIf


'
' Multiple statements in single-liners (separated by comma)?
'
If [expression] Then [statement1], [statement2], [statement3]

If [expression] Then [statement1], [statement2], [statement3] Else [statement1], [statement2], [statement3]

'
' multiple [statement] separated by comma is a [statement-list]
'
If [expression] Then [statement-list]

If [expression] Then [statement-list] Else [statement-list]

'
' Same for For..Next
'
For local value:=Eachin values
   sum+=value
Next [opt:var]

For local value:=Eachin values Do [statement-list]
For local value:=Eachin values Do sum+=value



For local value:=  1   To   10  Do  sum+=value  ' [statement-list]
For local value:=  1   To   10  Do  sum+=value
For local value:= 10 DownTo 1   Do  sum+=value

'
' While..Wend
'
While [expression]
    [statements]
Wend

While [expression] Do [statement]

While [expression] Do [statement1], [statement2], [statement3]
' becomes:
While [expression] Do [statement-list]

While function()=0 Do count+=1

'
' 'Do' and 'Repeat'
'
' (same thing with different linguistics for supporting differentiated thinking
'  and enunciation/phrasing -> freedom of mind to express thoughts in code)
'
Do [end-of-line]
   [statements]
While [expression]

Do [end-of-line]
   [statements]
Until [expression]

Do [end-of-line]
   [statements]
Forever

Do [statement] While [expression]
Do [statement] Until [expression]
Do [statement] Forever

Do [statement1], [statement2], [statement3] While [expression]
Do [statement1], [statement2], [statement3] Until [expression]
Do [statement1], [statement2], [statement3] Forever

Do [statement-list] While [expression]
Do [statement-list] Until [expression]
Do [statement-list] Forever


Repeat [end-of-line]
   [statements]
While [expression]

Repeat [end-of-line]
   [statements]
Until [expression]

Repeat [end-of-line]
   [statements]
Forever

Repeat [statement] While [expression]
Repeat [statement] Until [expression]
Repeat [statement] Forever

Repeat [statement1], [statement2], [statement3] While [expression]
Repeat [statement1], [statement2], [statement3] Until [expression]
Repeat [statement1], [statement2], [statement3] Forever

Repeat [statement-list] While [expression]
Repeat [statement-list] Until [expression]
Repeat [statement-list] Forever



Danilo(Posted 2015) [#5]
marksibly wrote:
***** Virtual constructors *****

If new() could also be a function, class ctors would be able to return subclasses, eg:
class C
   function new( arg:int )
      if arg=1 return New D
      if arg=2 return new E
      return new C 
   end
end

Class D extends C
end

class E extends C
end


I don't think that's necessary. Constructors should automatically return
the type of itself. For returning subclasses, you would then use a simple function/static method:
class C

   Method New()         ' Constructor
   End

   Method Constructor() ' Constructor
   End

   Function New:C( arg:int ) ' that's just a static method/function, no automatic constructor
      if arg=1 return New D
      if arg=2 return new E
      return new C 
   end
end

Class D extends C
end

class E extends C
end


marksibly wrote:
There are issues with this: new may return null (could return null on failure); new may not return unique instances (could return values from a cache). Either could be good or bad...

Failure to create an object would/should result in an exception, shouldn't it?


Derron(Posted 2015) [#6]
' Multiple statements in single-liners (separated by comma)?
'
If [expression] Then [statement1], [statement2], [statement3]


I would prefer the old approach of concatenating statements with semicolons.
As long as you do not enforce brackets SetColor(r, g, b) you introduce ambiguity.

I am also using "Then" for single-line IFs and none for multi-line ones. For "compatibility issues" you might not be able to change this behaviour for "Monkey 2".

bad:
If isDesiredImage GetImage 10 DrawImage GetImage 10, 10, 10


better:
If isDesiredImage( GetImage(10) ) Then DrawImage( GetImage(10) , 10, 10)




Failure to create an object would/should result in an exception, shouldn't it?

runtime =/= compile time.


@new-functions
As soon as someone "overrides" (introduces) a custom New()-function it is up to the developer to take care of whether things are null or not. Introducing checks there will lead to some unneeded workload for the processor.

bye
Ron


Danilo(Posted 2015) [#7]
@Derron
Thanks for reminding me. In my own syntax considerations functions/methods always use parentheses, of course.
Variables and properties are accessed without parentheses. Your bad/better example is fine for showing readability.

Using ; (semicolon) or : (colon) is perfectly fine with me. MonkeyX seems to enforce using the semicolon:
Function Main:Int()
    Local switch:Bool = True
    If switch Then f1(); f2(); f3()
    Return 0
End

Function f1:Void()
    Print "f1"
End

Function f2:Void()
    Print "f2"
End

Function f3:Void()
    Print "f3"
End

Whereas BlitzMax allows multiple statements without using a statement separator:
Function Main:Int()
    Local switch:Int = 1
    If switch Then f1() f2() f3()
    Return 0
End Function

Function f1()
    Print "f1"
End Function

Function f2()
    Print "f2"
End Function

Function f3()
    Print "f3"
End Function

Main()

Without using any statement-separator within [statement-list] can be confusing sometimes, in my opinion.

Forcing use of paranthesis for methods/functions also makes parsing easier and gives a nice and clean syntax.


Derron(Posted 2015) [#8]
Hmm always assumed BlitzMax used ";" to concatenate ...seems this is even not needed.

In that case the ambiguity could get even worse (functions with default values chained together).


bye
Ron


ziggy(Posted 2015) [#9]
Several considerations:

1.- Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.

2.- Also, allowing a right-to-left parsing (that is, not using < and > for generics, such as in D, or VB, etc.) makes writing intellisense systems much more simpler, and prevents impossible to single-pass parse isntructions such as this one:
If MyShomething(identifier1)<identifier2>(identifier3) Then Identifier4

It is impossible to know if this is a typecase operation with generics, or a comparison operation. MySomething could be a function or a class name, where identifier2 could be a class name or a local variable, while identifier3 can be anything. That makes the operator < and > impossible to understand unless surrounding ones are completely lexed, which is not exactly very nice (requires 2 phases at best). D has a nicee way to disambiguate this quite nicely [a http://en.wikibooks.org/wiki/A_Beginner's_Guide_to_D/Templates_and_Generic_Programming/Template_Classes ] see here [/a] Also vb.net uses Of operator for the same reason.


Michael Flad(Posted 2015) [#10]
If anything, make constructors (well new actually) work with a given block of memory - i.e. placement new alike.

Performance these days is so dependent on a cache optimized data layout and it kind of kills langauges like C# for high performance inner loops. With the quite absurd results that it's so common not to write fast code because users of the languages measure there's hardly a benefit (and learn that it's not required to write fast code anymore) when the real bottleneck is the cache/memory that's slowing down the whole thing by factor of 10 or even more already.


degac(Posted 2015) [#11]
Why do you want create unuseful syntax complications?

for local value:=eachin values sum+=value

for local value:=eachin values
sum+=value
next

Just to gain 2 lines and one word?
I don't think or value it as an important factor in a language.
In any case, until I can use the second approach I'm happy.
But I think that approach 1 makes hard to read the code.


Nobuyuki(Posted 2015) [#12]
Danilo's "Do" seems like a pretty decent catch-all for single-line statements requiring an expression that would normally need an entire code block. In other threads I suggested "Returns" for this, but it was specifically for function definitions such as lambdas and property getter/setters, whereas "Do" sounds like it would be readable on nearly any type of statement to separate the expression part from the rest. Agreeing with everyone else in here who said that not enforcing parenthesis on method/function calls introduces a lot of ambiguity which probably hurts parsing the code. Using <> for generics makes it easier to read, though I wonder how messy that will get if closures get involved. I don't know about the difficulties in parsing/lexing code, since I've never written a compiler nor a code editor, so take what I say with a grain of salt.


Pharmhaus(Posted 2015) [#13]
Well I am not sure if this is the right place to put this, but one of the things that I miss in Monkey a lot is the lack of (fake) overloading for the slicing operator [..]
and the index operator. For example, in C# you can simply define an own index operator in your class and this is used by the normal .NET data structures such as List and Dictionary.



Another thing that could be improved in MX2 is the inability to define Maps and the like in a really generic way. One has to use stringmap, intmap etc.
It would be cool if you could do something similiar to C#s "Default(T)" which returns the default value for the type T.





Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.


+1


Nobuyuki(Posted 2015) [#14]
@Pharmhaus
Another thing that could be improved in MX2 is the inability to define Maps and the like in a really generic way. One has to use stringmap, intmap etc.
It would be cool if you could do something similiar to C#s "Default(T)" which returns the default value for the type T.


Since we're on the subject, it would be nice to migrate all containers to take a standard generic Comparator<T> (or implement Comparable<T>) so that sorting can be done based on however we want, without having to necessarily extend the classes to do this.


EdzUp(Posted 2015) [#15]
Basically blitzmax with 64bit support and a possibility of 3d


Samah(Posted 2015) [#16]
@marksibly: If new() could also be a function, class ctors would be able to return subclasses, eg:

Eww... constructors are for instantiating the class they belong to. If you want to do magic code to select subclasses, you should be using a factory pattern.
Also, please please please allow calling other constructors: Self.New()

@marksibly: Don't really get that code - what's the point in 'Closure' being generic if all types are known?

Local foo:Closure<String> is like void (*foo)(String);

@ziggy: 1.- Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.

+1, but good luck convincing most developers. I got shot down when I suggested this for Monkey.

@Nobuyuki: Since we're on the subject, it would be nice to migrate all containers to take a standard generic Comparator<T> (or implement Comparable<T>) so that sorting can be done based on however we want, without having to necessarily extend the classes to do this.

Or Mark could just include Diddy containers with Monkey. :)

@EdzUp: Basically blitzmax with 64bit support and a possibility of 3d

3D support will be a module and not part of the language scope.


Skn3(Posted 2015) [#17]
I am late to the party in this thread so may be re-stepping what has already been said, but a massive +1 for constructors being able to decide what they return.
(from another post)
Class Base<T>
	Global pool <T>:= New Pool<T>
	
	Method New()
		If pool.IsEmpty()
			Return New T
		Else
			Return pool.Pop()
		EndIf
	End
	
	Method Destroy()
		pool.Push(Self)
	End
End

Class Item Extends Base<Item>
End

Function Main:Int()
	Local i:= New Item
	Destroy i
End


Something like this would be so clean! (also with pseudo destructor :)


Skn3(Posted 2015) [#18]
Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.


+1


ziggy(Posted 2015) [#19]
@ziggy: 1.- Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.
+1, but good luck convincing most developers. I got shot down when I suggested this for Monkey.

Well, ; is now allows in Monkey to concatenate statements in the same line, but only inside method and function bodies. I would suggest it to allow it everywhere, or nowhere. The fact that they can be optional at the end of a sentence, when the sentence ends at the end of the line, is ok for me, as it is constant and equal everywhere.
Class MyClass Extends Another
    Private _myID := 45
    Field myField := 5

    Overrides Property MyNumber() ; Getter; Returns myID; End
    Overrides Property MyName$(); Getter; Returns "Paul"; End
    Overrides Property Whatever%() ; Getter; Returns Rnd(0,5); End

End

Not that I like the way I've used in the sample above, just tried to explain what I meant.


Nobuyuki(Posted 2015) [#20]
@ziggy
I'd rather see semicolons be allowed everywhere than to see line-returns as terminators allowed nowhere. This is a BASIC dialect we're talking about here... Perhaps the way to solve the difficult parse/lexing would be to eliminate the ambiguous line continuation rules and just force a line continuation character instead? (VB uses " _ " for this)


Danilo(Posted 2015) [#21]
Shouldn't private constructors be possible in MX2?
Class Item

    Private

        Global pool:= New List<Item>
    
    	Method New()
        End
    
    Public
    
        Function GetInstance:Item()
            If pool.IsEmpty()
                Return New Item
            Else
                Return pool.RemoveLast()
            EndIf
        End
    	
        Method Destroy()          ' pseudo destructor
            pool.AddLast(Self)
        End

End


Function Main:Int()
    Local i:= Item.GetInstance()
    Local j:= New Item()          ' shouldn't work, Constructor is private
    i.Destroy()
    j.Destroy()
End



ziggy(Posted 2015) [#22]
@ziggy
I'd rather see semicolons be allowed everywhere than to see line-returns as terminators allowed nowhere. This is a BASIC dialect we're talking about here... Perhaps the way to solve the difficult parse/lexing would be to eliminate the ambiguous line continuation rules and just force a line continuation character instead? (VB uses " _ " for this)

I0m okey with "latest token is operator" rule for line continuation. In fact, modern VB does this too! (no need for the _ char, or the .. of BlitzMax). the issue is that Monkey1 allows for situations where you can directly avoid the ; operator and the parser just ignores this.

This code compiles:
Function Main()
	Local name:= "Hello" Print name If name <> "Hello" Print "Unexpected error"
	Local i:= 1 While i < 10 i += 1 Print i Wend
End

but according to language specification, it should be like this:
Function Main()
	Local name:= "Hello"; Print name; If name <> "Hello" Print "Unexpected error"
	Local i:= 1; While i < 10; i += 1; Print i; Wend
End

I do honestly think that the compiler is just considering the semicolon as whitespace.


DruggedBunny(Posted 2015) [#23]
I never liked that in Monkey either (or functions returning values without brackets!), not that it affected me. Statement separators being always ; seems much tidier, as long as they're not required at the end of a line.


Local name:= "Hello" Print name If name <> "Hello" Print "Unexpected error"


Yeah, that's a weird combination of vague and horrendous!


Nobuyuki(Posted 2015) [#24]
Wow, I had no idea that passed the compiler at all. Now I think I understand what you meant the first time around.

Does that pass the compiler in Strict mode? Mark did mention something like Monkey2 operating in a "Strict" mode by default, which I'm presuming means that functions will require parenthesis now and (I'm presuming) that kinda code would not get anywhere close to compiling...


JoshKlint(Posted 2015) [#25]
I don't really care about new language features over BMX other than function and operator overloading, and constructors.


ziggy(Posted 2015) [#26]
@JoshKlint: Generics and Delegates, once you start using them, you'll love them too!


nullterm(Posted 2015) [#27]
1.- Please, don't make ";" optional as it is now, in some places in MonkeyX. Making it consistent everywhere can make writing fast IDE parsers a lot easier and efficient.


No! This is one of my favourite "features" of Monkey, not needing to write bloody ;'s all over the place. I love the simplicity of life without semicolons.

Requiring semicolons between statements is holdout from decades ago when compiler writers made programmers jump through crazy syntax hoops to make their own lives easier.


nullterm(Posted 2015) [#28]
I just found this forum, and I have to say the prospect of a Monkey 2 has me more excited than Christmas.

Destructor/Finalize - This would make life so much easier collecting resources like OpenGL vertex buffers, textures, etc. I know in a gc based system the timing is random, but would make life easier/safer.


ziggy(Posted 2015) [#29]
No! This is one of my favourite "features" of Monkey, not needing to write bloody ;'s all over the place. I love the simplicity of life without semicolons.
I was talking about sentences in the same line. I explained here: http://www.monkey-x.com/Community/posts.php?topic=9713&post=102686


PixelPaladin(Posted 2015) [#30]
First of all:
Hello Everyone! (it's my first post here)


It seems that this is the right place to post a list of language features I would like to see in Monkey2.


Enumeration:

Enum Day
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
End

For i:Day = Wednesday To Friday
	Print i
End

' output:
' 2
' 3
' 4


Some syntactic sugar:

a:Map<String, Int>

a["foo"] = 123 ' -> a.Set("foo", 123)

Print a["foo"] ' -> Print a.Get("foo")


All the cool lambda stuff, function factories, closures, ...

Function CreateAdder:Int(Int)(i:Int)
	Function Adder:Int(x:Int)
		Return x + i
	End
	Return Adder
End

MyAdder = CreateAdder(3)
Print MyAdder(24)

' output:
' 27


Built in signals and slots:

Class MyClass1
	Signal Foo(String, String)
End

Class MyClass2
	Slot Bar(a:String, b:String)
		Print a+" "+b
	End
End

Class MyClass3
	Slot FooBar(a:String, b:String)
		If a = b Then Print a+" = "+b Else Print a+" <> "+b
	End
End

x := New MyClass1
y := New MyClass2
z := New MyClass3

Connect(x.Foo, y.Bar)
Connect(x.Foo, z.FooBar)

x.Foo("hello", "world") ' -> emit x.Foo

' output:
' hello world
' hello <> world


Something like an Invoke()-Method would be interesting (I used this for hacking lambda functionality into the monkey 81b translator):

Class Bar
	Invoke:Void(x:String)
		Print x
	End
End

foo := New Bar

foo("hello")

' output:
' hello


Some possibility for making lines shorter for better readability:

Function SomeFunction:SomeType(parameter1:Xyz, parameter2:Xyz, \
                               parameter3:Xyz, parameter4:Xyz, \
                               parameter5:Xyz, parameter6:Xyz, \
                               parameter7:Xyz, parameter8:Xyz)
	{...}
End


Last but not least: It would be nice to have some scripting language support (maybe lua) - but that is not really a language feature ...


Samah(Posted 2015) [#31]
@PixelPaladin: Some possibility for making lines shorter for better readability:

Monkey already does this for some operators. You'll find if you remove those backslashes in your code example, it will already compile in the way you're expecting.

@PixelPaladin: It would be nice to have some scripting language support (maybe lua)

Hasn't been updated in a while, but:
http://code.google.com/p/monkeylua/


PixelPaladin(Posted 2015) [#32]

Monkey already does this for some operators. You'll find if you remove those backslashes in your code example, it will already compile in the way you're expecting.


Sorry - I didn't know that. I think it was not possible in older versions. I will clean up my source codes immediately :)


Hasn't been updated in a while, but:
http://code.google.com/p/monkeylua/


To be more precisely, I meant that with only the main desktop and mobile platforms left, it would be nice to have scripting support for all platforms in monkey2 - including android and ios. If the current native modules could be used in monkey2, monkeylua would be a good starting point for this.


Samah(Posted 2015) [#33]
@PixelPaladin: ...including android and ios.

Since it just wraps the official Lua API, MonkeyLua will (theoretically) work for any C target, which means GLFW, iOS, and Android (NDK).
I'm not sure if it compiles/works with the latest version of Monkey, so if people are interested I can update it and look at getting some other targets working.

When I first started MonkeyLua, it was a port of a C# implementation to pure Monkey. This turned out to be infeasible due to Monkey's lack of structs and pointers, since it would mean simulating them using objects and arrays. All these objects would be death for the GC. I opted instead to just wrap the C API.

As for Monkey2, if it supports structs and pointers, etc. I'll be able to clone the Lua VM in pure Monkey2 source.


marksibly(Posted 2015) [#34]
Lots of good ideas there PixelPaladin, and I'll try get as many of them going as I can!

One thing I would like to do is NOT have a separate Signal/Slot concept - instead, you should be able to use function ptrs, eg:

class Source
   field Signal:void()
end

class Target
   method Slot:void()
   end
end

function main:void()
   local s:=new Source
   local t:=new Target
   s.Signal=t.Slot
End


The problem with this of course is that you can only connect 1 slot up to a signal at a time, so some kind of multicast system needs to be added. C# hardwires this into delegate I think, but it'd be nicer if you could code it up yourself somehow, so you could control the order slots are called, what to do with return values etc.

One idea would be to use something like C++ variadic template parameters to allow 'Invoke' methods to be written, eg:

class Signal<F>
   field _slots:Stack<F>

   method AddSlot:void( slot:F )
      _slots.Push slot
   end

   method Invoke<...>:F.ReturnType( ... )
      for local slot:=eachin _slots
         slot( ... )
      next
   end

end


Ok, very much off the top of my head, syntax wouldn't probably work etc, but I think it'd be very flexible.