Language suggestions

Community Forums/Monkey2 Talk/Language suggestions

JoshKlint(Posted 2015) [#1]
This thread is for posting my input on the actual language, based on my experience with BMX, C++, Lua, Maxscript, etc. My suggestions are mostly about eliminating ambiguity in the language.

The language should be case-sensitive. This saves pain in the long run, and also allows natural expressions like image:Image.

'endif', 'next', etc. should be used instead of the Lua-like 'end'. It makes it easier to tell what's going on when you are looking at the end of a large block of code. 'end' is the worst of both worlds because it has the verboseness of BASIC together with the ambiguity of brackets.

The BlitzMax strict/superstrict modes should be eliminated, and just always run in the equivalent to 'superstrict'. How many times have you copied some code from the forum, only to find out you have to go through and define all the variable types?

I recommend eliminating globals in functions and functions in functions. They are not frequently used, and I have encountered some very bad errors in these. Generally if you have an alternative way of doing things, it will not be tested as well and you will discover problems over time. These don't add a lot of value to the language, and it's just better to have one right way of doing things.

Direct use of C++ classes from external libraries would be wonderful. We don't support BMX / Monkey in Leadwerks 3 because it's not worth creating and maintaining a procedural API for. I understand this means using the same compiler the library was built in, so that means the Visual Studio compiler should be an option on Windows.

Debugging is paramount. I don't know much about this in Monkey, or how it would work to debug C++ code and line it up to the original language.

BlitzMax types act like C++ pointers. It would be useful to have a "struc" object that acts like C++ objects:
Struc Vec3
Field x#,y#,z#
EndStruc

Local a:Vec3
Local b:Vec3
a.x = 1
b = a' copies the object, not the pointer
b.x += 1
if a.x = b.x 'This is false

Operator overloading would go along with this really well.
Local a:Vec3, b:Vec3, c:Vec3
a.x = 1
b.y = 2
c = a + b


Better syntax for maps, by whatever means necessary. This:
map["hello"] = "hi"


Is much much better than this:
map.insert("hello") = "hi"


Just don't use STL's terrible approach that adds a value to a map, and forces use of the iterator = find() if iterator!=end() method:
if map["hello"]=="";// inserts new value into map


That's all I've got.


GW_(Posted 2015) [#2]
I agree with all of this, except Global/static variables in functions. Every major systems language out there has them for a good reason.
Also, I use nested functions a lot in BMax, but I won't cry if they go away.
Maps implemented as a library is fine with me too.
Personally, I love that Bmax is case insensitive, but it's just not possible if your going to be targeting C++.
The severe downside of case sensitivity is that highlights the critical need for an IDE that supports intellisense. A MaxIde/Ted style editor just won't cut it anymore and forces the users into a painful, captive-audience situation with *other tools.
Monkeys debugger is really lacking compared to Bmax in that globals, Const, and deep inspection etc are missing, I hope it's in the cards for M2 to have at least Bmax quality debugging.
I would also add that a callstack sampling profiler is near the top of my list of things that I hope M2 will support.


DruggedBunny(Posted 2015) [#3]
I actually love End for block ends, and it bugs me in Max when I have to type in full -- I haven't found any ambiguity, given indentation shows the context. You can use EndIf, End Function, etc, anyway in Monkey1.

I like functions-in-functions, though they're not essential. I thought it was useful to stick a function used only by a single function (over and over) inside the calling function.

Monkey1 is effectively Strict by default, with SuperStrict forcing Returns even where not needed, which is just a PITA, hence I don't use it. Wouldn't be the end of the world if it was the default, though.

I'm in the case-sensitive camp for variables now, where I never used to be, though admittedly I'd prefer if Ted did auto-capitalisation of Mojo/Monkey functions at least...


Direct use of C++ classes from external libraries would be wonderful.


Definitely, but is it even do-able if the classes include advanced C++ features not actually offered in Monkey2?

I'd like plain structs too, if possible.


ziggy(Posted 2015) [#4]
Functions inside functions are very useful in parallel programming and, if they can be anonymous (as lambdas), it's even better when you work with delegates. This can provide a quite useful highlevel approach to milti-threading that is several orders of magnitud better than using some APIs over a language that is not thought to be multi-threaded from its design. I don't know if Mark is thinking in adding this for exactly this reason, or there are other reasons, but those are very useful language constructions.

Expressions like this, make writing parallel multi-thread code a breeze (imagine MyParticlesList is a LinkedList of MyParticle instances.
Function ProcessParticles()
	Local myFunction:= Function (particle:MyParticle)
				If particle.timer<0 then particle.Kill() else particle.UpdatePos()
			End Function
	Parallel.ForEach(MyParticlesLists, myFunction)
End Function



Pharmhaus(Posted 2015) [#5]

I agree with all of this, except Global/static variables in functions. Every major systems language out there has them for a good reason.


Not useful every single day but sometimes and especially because there quite some blitzers out there who still prefer to code a not-so-oop way.


Functions inside functions are very useful in parallel programming and, if they can be anonymous (as lambdas)


Really hoping for closure / lambda / whatever support



Talking about language features Rubys ability to add new methods to existing classes and C#'s extension methods come to mind.
I also sometimes miss things such as C#'s ExpandoObject. Which basically allows one to add e.g. new properties at runtime and is both faster and usually cleaner to read/write than refletion.
dynamic obj = new ExpandoObject();
obj.Value = 10;
var action = new Action<string>((line) => Console.WriteLine(line));
obj.WriteNow = action;
obj.WriteNow(obj.Value.ToString());

It is also possible to cast ExpandoObject to IDictionary when necessary. So it is possible to handle it as if it was a Map and you can simply insert values (fields/properties) which is extremly nice.


Thinking about it, one of the things that I miss like hell is the ability to define generic methods in not generic classes.

Class Abc
	Method xyz <T>:Void()
		Print Default(T).ToString()
	End
End


It is really annoying when you can only pass one type of T to a method that is totally bound to a class even if the method could take other types as well.


Samah(Posted 2015) [#6]
@Pharmhaus: Thinking about it, one of the things that I miss like hell is the ability to define generic methods in not generic classes.

You can kinda fudge it using static functions and by overloading your "generic" method for each data type. I did this in Diddy's IComparator stuff so the sorting could "cast" primitives to an interface.
Class Foo<T>
	Function Hello:Void(val:T)
		' do stuff with val, but you need to check what type it is
	End
End

Class Bar
	Method World:Void(val:Int)
		' int version
	End
	
	Method World:Void(val:Float)
		' float version
	End
	
	Method World:Void(val:Bool)
		' bool version
	End
	
	Method World:Void(val:String)
		' string version
	End
	
	Method World:Void(val:Object)
		' object version
	End
End

Foo<Int>.BarFunc(123)
Foo<String>.BarFunc("hello")

Local a:Bar = New Bar
a.World(1)
a.World(3.14)
a.World(True)
a.World("hello")
a.World(New Object)


@Pharmhaus: Talking about language features Rubys ability to add new methods to existing classes and C#'s extension methods come to mind.

Same with Objective-C categories, which I asked for in Monkey 1 but no-one seemed interested. Let's hope they're easier to implement in Monkey 2.
http://www.monkey-x.com/Community/posts.php?topic=2314

@JoshKlint: 'endif', 'next', etc. should be used instead of the Lua-like 'end'. It makes it easier to tell what's going on when you are looking at the end of a large block of code.

I've never had a problem with this, and Monkey supports both anyway.