Any news?

Community Forums/Monkey2 Talk/Any news?

Danilo(Posted 2016) [#1]
How is MX2 development going? ;)

Especially, is there any estimated date for a new Demo, the first Beta, or anything like that?
Week-long silence between every single blog post can be little bit confusing and de-motivating -
likewise Patreon supporters seem to get less and less every month (maybe because there are no news).


degac(Posted 2016) [#2]
Having some new posts would be interesting :)
A beta to play with, a great surprise !
Personally I moved from Patreon only for a 'tax' question... I need to pay VAT on the donations: no thanks.


Danilo(Posted 2016) [#3]
Yeah, 19% extra tax on top of the donation, 5% of the donation goes to Patreon, and there are
credit card and PayPal fees taken from the donation. The Creator receives probably 74% only from
what I actually pay alltogether.


marksibly(Posted 2016) [#4]
I'll make a more detailed update post later today, but basically I've been fine tuning the language/compiler and working on the standard modules.

Kinda boring stuff, but the new compiler (now in 100% mx2) is a LOT more solid than the old version was. It includes a level of sanity checking I have probably not put into *any* compiler to date! I even have some 'tests' in there(!) mainly for 'delicate' features that I somehow keep managing to break when I tweak other things. I have also decided on how some things will work that were previously kind of 'up in the air' - for example, how comparison overloading works.

All of which is not very exciting, but mx2 now feels much more 'finished' to me than it was at the start of the year.

I will probably be doing a 'compiler only' release soon for people that just want to play around with the language, with another release later that will include mojo/mojo2 etc once they have received more attention.


tiresius(Posted 2016) [#5]
Having mx2 compile itself is a milestone. Congrats !


Danilo(Posted 2016) [#6]
Thanks, Mark! Compiler-only release opens some questions about the included libs.
For example, I asked myself why are general libs not more opened/separated? Had to use/include
whole lib.c thing if I wanted to include lib.c.sdl only. Maybe such mayor includes, like SDL and OpenGL, should
stay on their own instead of being included into a sub-namespace/lib?

Including/Compiling lib.c.sdl only didn't work with xmas-demo v2 - had to include whole lib.c (many libs included that I don't need).
Libs like SDL (and OpenGL, ZIP (un-)compression etc.) are stand-alone (and can be used like that, by any other lib that uses them),
so they shouldn't be coupled/bound/integrated into some sub-namespace/lib in MX2, in my opinion. They have nothing to do with MX2 mojo/mojo2 etc., after all.


marksibly(Posted 2016) [#7]
> For example, I asked myself why are general libs not more opened/separated?

The original intent was to duplicate the pub/brl modules setup in bmx where pub contained low level 3rd party libs and brl contained 'adapters' so they were more usable from the bmx side. For example, pub.libpng contains a raw interface to the png lib (so it's kind of hard to use - but still there if you want to use it) while brl.pngloader contains a nicer bmx friendly pixmap loader. I quite liked how this worked as each 'lib' effectively consisted of 2 modules - the low level ugly stuff module, and the nicer bmx module.

But I now agree that modules should be much more finely grained, and it can be left up to the author to deal with adapters for std.Stream or whatever, either in the lib module, or via an extra module.

Which raises the question - do we even need 'std'? Stream, Pixmap, DataBuffer etc could be individual modules and go in their own namespace instead of a common 'std' namespace. This does mean more 'Using' statements in an app but it follows a similar philosophy. This was another reason for having a monolithic 'lib' module - it was supposed to represent the 'system' lib modules that were part of 'core monkey' in a similar way to 'std' (the difference being std was pure mx2 code - ala pub/brl), but maybe it makes more sense to go for a super fine grained approach and just have a huge module soup?

Once people can contribute modules, I guess there is the danger of polluting everything with dodgy modules, but these wouldn't appear in the BRL monkey2 repos or in BRL monkey2 releases so perhaps it's a non-issue?

I'm definitely not afraid to mix things up here anyway - moving modules around is pretty painless in mx2 - so any ideas are most welcome!


dawlane(Posted 2016) [#8]
@Mark: Speaking of modules. Is there any chance of making it so that the compiler is capable of looking for a directory containing modules in the users own home directory before looking in mx2's own.


Danilo(Posted 2016) [#9]
Thanks, Mark! I don't know anything about BlitzMax, so the explanation of pub vs. brl namespace is new to me, but makes sense.
Just wondered why major stand-alone includes like Win32, OpenGL, SDL etc. should be within another namespace and module.
Effectively, if I need to Import lib.c, MX2 imports everything from this module, even If I need only raw SDL for example.

That brings me to another point. While libs in MX2 are compiled to make the build process faster, the definition of the functions,
classes, methods, structs, constants, etc. need to get parsed every time.
So if you import something big, like a 3D engine, QT framework, or something similar, the code is compiled one time (or a static lib is imported),
and the process of linking is usually very fast.
But MX2 has to know everything about the lib, and those Import files with Extern declarations are parsed every time you compile
your own source that uses the lib.

I have the feeling this process of parsing can get time consuming the bigger the imported library is. We are talking about
something like 350 classes, 50 Enums, 150 Constants, and let's say 20 methods per class (just as an example).
While the parser is very fast, I think it can get slow if it needs to parse this same extern import declarations over and over again.
If those 350 class definitions are in 350 separate files, MX2 needs to load + parse those 350 files every time I compile a small code
that imports the lib.
It's probably the same with other big frameworks like QT (probably also some hundred classes), or WinAPI function imports
that could be some ten-thousand functions, some thousand structures, constants, Enums, etc.

Instead of parsing those big imports every time, it could be done only once (first time, and when the lib changes).
MX2 could generate something like a binary pre-compiled header file that contains all declarations for functions, classes,
methods, enums, constants. Loading this pre-compiled header is usually much faster, because the compiler does
not need to parse raw string input. Instead it loads data/strings directly into lists/arrays/maps (compiler's symbol table),
without actually parsing the strings again. Pre-compiled header files could contain sorted data, so loading is as fast as possible.

Compiler could have a switch to generate a pre-compiled header file:
compiler -genpch input.monkey2 -out libname.mx2pch


App sources still use ordinary imports:
#Import "<TheLib.monkey2>"

and the import file would look like this:
#Import "TheLib.a"      ' static lib
#Import "TheLib.mx2pch" ' MX2 pre-compiled header


What do you think?


taumel(Posted 2016) [#10]
You could ask Brucey about his opinion. He has a little bit experience in this area. As Max, Monkey and open sourcing older products have shown, a minority is interested in expanding a tool, the majority just wants to use it. Therefore i would try to enhance the import process but without hurting the experience for those who will never touch it. I like Max's pub/brl setup.


EdzUp(Posted 2016) [#11]
To be honest I prefer Import and importing something would automatically setup the 'Using' section without needing the call the command, all the Using std etc seems superficial if you already need to Import something in the first place. If we are jumping to a C++ like framework and command syntax then MonkeyX2 will be compared to it which may not be a bad thing but it depends on its capabilities.

for example:
#Import "<mojo.monkey2>"

Using std
Using mojo
Using mojo2

Class MyWindow Extends Window

	Method New()
		Super.New( "My Window",0,0,640,480,WindowFlags.Center )
		
		Destroyed=App.Terminate
		
		ClearColor=Color.Black
		
		'Load resources here...
	End
	
	Method OnRender( canvas:Canvas ) Override

		App.RequestRender()
		
		'Mojo2 rendering code here...avoid SetScissor and SetViewport for now.
	End

End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End


Import mojo.monkey2 imports all the mojo system etc so the 'Using std', 'using mojo' and 'using mojo2' seems superfluous and not required. If you want a better uptake of monkeyX2 having barriers to the language to make simple things will cause people to look elsewhere. If your after a 'Framework' like system from BlitzMax why not actually just have one this was one of max's strong points as it could compile smaller executables if required but for the layman it was very easy to pick up and use. Making a language convoluted and have commands that dont really help much will cause issue with some.


impixi(Posted 2016) [#12]
@EdzUp:

Here's Mark's faq about namespaces:

http://monkey2.monkey-x.com/forums/topic/namespaces-and-using/

See the bottom of the faq for an explanation about "Using".

There are significant benefits to having namespaces, especially for larger projects spanning many files. Sure there is a "complexity" cost - though in this case I'd argue it's small for the benefit received. And it's a more flexible, tidier approach than the Blitzmax way, IMO...


Nobuyuki(Posted 2016) [#13]
I like namespaces mainly because sometimes I want to fully qualify a function call, especially if it means we'll have shorter named ones (if we want to import the namespace), less aliasing problems, etc. With a proper hierarchy, it could also have a much easier way for people to tinker/explore libraries in a proper IDE. Think something like a newbie looking for mojox.graphics.Image.Load(blah), instead of having to know that the function is LoadImage(). Same with something like brl.io.buffers.DataBuffer, blah blah etc. A newbie can start typing a root namespace and start looking around in there for something related to what they want to do, ideally with the hierarchy letting them "drill down" excluding anything that might not be entirely appropriate.


taumel(Posted 2016) [#14]
@Mark
How are collisions handled (when using more than one, like in C#)?


EdzUp(Posted 2016) [#15]
@impixi: ah I see why now its a basic way of cutting down the code length by telling the compiler to look elsewhere. I have used namespaces in C++ but I can see what they are and how different they are in Mx2


Danilo(Posted 2016) [#16]
Removed. I'm in doubt people (want to) understand what I'm trying to communicate openly. :(


taumel(Posted 2016) [#17]
Nope, you're right but that's Mark.


marksibly(Posted 2016) [#18]
Ok, I've posted a little update at the monkey2 site!

> Instead of parsing those big imports every time, it could be done only once (first time, and when the lib changes).

This is certainly doable but not a priority right now as parsing/semanting are pretty quick, esp. for extern decls as the compiler doesn't have to do much with these.

But if parse/semant times do start becoming a problem, I'd probably want to do some profiling first before decided on the best fix. I vaguely remember the 'D' guys working out the compiler was spending 90% of its time in NextToke(), and someone converting it to ASM for a MASSIVE speed up!

And there are probably a ton of optimization opportunities in the mx2 compiler - I've paid attention to algorithmic complexity, but have been a bit lax with everything else. And I definitely do want to add -config=profile once the debugger is in....

> How are collisions handled (when using more than one, like in C#)?

You mean collisions between namespaces? There's no such thing really, as namespaces are 'open' so multiple files (even in different modules) can add things to the same namespace.

> Removed. I'm in doubt people (want to) understand what I'm trying to communicate openly. :(

?

> Nope, you're right but that's Mark.

??


Nobuyuki(Posted 2016) [#19]
newest update is interesting. I'm not aware of any languages that have sorting comparisons as an intrinsic operator, but I can imagine that there are places where this would be convenient. I can also imagine places where this could be dangerous! If the behavior is arbitrary (and not well defined) then it could easily get some people into trouble when it shoots back an unexpected value.


marksibly(Posted 2016) [#20]
> If the behavior is arbitrary (and not well defined) then it could easily get some people into trouble when it shoots back an unexpected value.

Well, it'll always produce the *same* result whenever the same 2 objects are compared so the result itself is never 'unexpected'. And short of doing some hackery to get an object's address, you can't know *what* to expect.

The only danger really is forgetting to implement a comparison operator for objects that you want to be compared in some special way.


Danilo(Posted 2016) [#21]
Which language elements from the MonkeyX 2 Roadmap are available with the new demo (later this week)?
Is 'extends Null' already working? Thanks in advance!


taumel(Posted 2016) [#22]
>>> You mean collisions between namespaces? ...
I mean when you would use Using math.gfx2 and Using math.gfx3 in the same file and both would have a function with the same name. Which one would be chosen then (also if there exist the same overloaded options)?

>>> ??
This was my response to Danilo where he was frustrated about the lack of communication between you and the community, like more updates from you on what you're doing, when to expect a new release, why do questions from users do not get answered, he found this to be disrespectful and demotivating for the success of this open source project.


Gerry Quinn(Posted 2016) [#23]
> > If the behavior is arbitrary (and not well defined) then it could easily get some people into trouble when it shoots back an unexpected value.

> Well, it'll always produce the *same* result whenever the same 2 objects are compared so the result itself is never 'unexpected'. And short of doing some hackery to get an object's address, you can't know *what* to expect.

Java doesn't have a built-in comparison operator, but it does have the object equality ==() operator, which is kind of the same thing. It does lead to gotchas for beginners trying to do string comparisons, because the lack of operator overloading means that there has to be a separate equals() method for determining whether objects are actually equal, rather than whether they are the same object, which is what ==() tells you.


marksibly(Posted 2016) [#24]
> Which language elements from the MonkeyX 2 Roadmap are available with the new demo (later this week)?

'? Else' and 'Extends Void' are in. I went with Extends Void instead of Extends Null because it makes more sense to me - Extends should be followed by a type.

For now, you'll need to provide you're own 'delete' for Extends Void classes, eg:

Extern
Class T Extends Void
Function Destroy( t:T )="delete"

(I'm reserving 'Delete'!)

'? Else' is mx2's equivalent to C's '?:'. I prefer 'Else' to ':' because I find it a bit easier to read and ':' is already used for typing.

So you can now go:

Local t:=x<y ? 10 Else 20

I would have actually liked to have used 'Then Else', but this confuses the parser in If statements.


Paul - Taiphoz(Posted 2016) [#25]
Posted this elsewhere but I guess can apply to MX2 as well, I was thinking something like this might be good

   Select Something
      Case #
            This Hash would be replaced at compile time for the number 1
      Case #
            This would be 2  etc......
      Case #
            blah
   End Select


It would allow us to have rather large select's and be able to insert things into the middle of them without then having to go down the list renumbering all the other case calls to account for the new addition.

I have a select block which is 150+ long and need to be able to insert new bits in specific points which means if I add in something at Case 10 then I need to renumber everything from the old 10 all the way down to 150+.. which is a pain.


marksibly(Posted 2016) [#26]
Eeek! What are you actually doing?


impixi(Posted 2016) [#27]

I have a select block which is 150+ long and need to be able to insert new bits in specific points which means if I add in something at Case 10 then I need to renumber everything from the old 10 all the way down to 150+.. which is a pain.



Consider my curiosity piqued. What are you trying to do? There's probably a better way to solve your problem (no disrespect intended).


marksibly(Posted 2016) [#28]
This sounds like a job for...On Goto! (if anyone remembers that...).

Perhaps it's for an 'instruction set' of some sort?

Here's one possible approach in monkey2:

Function Func1()
	Print "Func1"
End

Function Func2()
	Print "Func2"
End

Function Func3()
	Print "Func3"
End

Global funcs:=New Void()[]( Func1,Func2,Func3 )

Function Main()

	For Local i:=0 Until 3
		funcs[i]()
	Next
End


(and...whew...it works...)

Note the new syntax for array initializers, ie:

New T[]( value0,value1,value2... )

...replaces...

[value0,value1,value2...]

I changed this because having to make every element of the 'literal' array the same type was silly/awkward.


Danilo(Posted 2016) [#29]
> '? Else' and 'Extends Void' are in.

Very nice, thanks! :)


Difference(Posted 2016) [#30]
Here's one possible approach in monkey2: ...

Sweet!


dmaz(Posted 2016) [#31]
I changed this because having to make every element of the 'literal' array the same type was silly/awkward.
ah, totally awesome!


Danilo(Posted 2016) [#32]
@dmaz:
Looks like you understood that sentence and you came to the conclusion that it's awesome.
Do you have an example for what it would make better?
I didn't understand it, and i think all elements of an array are always of the same type -
but the sentence seems to indicate that it's silly that all array elements need to be of the same type...!?
Mark's example uses 3 function variables of the same type, not different ones. I'm Confused.

The one thing I noticed is that you have to use 'New' for everything. Structs, Classes,
Array Initializers - always need to use 'New'.

C++, using local struct Point:
Point pt;

MX2:
Local pt:Point = New Point

or
Local pt:= New Point

It's consistent to always have to use 'New'.


marksibly(Posted 2016) [#33]
> but the sentence seems to indicate that it's silly that all array elements need to be of the same type...!?

By 'elements', I really meant the list of values monkey uses to 'deduce' the type of the array. For example, this generates an error in monkey1...

[ 1.0 , 2 , 3 , 4.0 ]

...since the 'elements' contains both ints and floats, so monkey can't work out what type of array you're talking about. An int array? A float array?

This is sometimes easily worked around (in this case, just use all float literals if you want a float array) but where it really sucks IMO is when you want to do something like...

[ Derived1,Derived2,Derived3 ] 'Error! Not all elements of same type so monkey can't work out array type.

...you end up having to go...

[ Base( Derived1 ),Base( Derived2 ),Base( Derived3 ) ] 'Ok, but yuck.

...now you just go...

New Base[]( Derived1,Derived2,Derived3 )


Danilo(Posted 2016) [#34]
I understand now, thanks for clarification!


FelipeA(Posted 2016) [#35]
Hi Mark,

I've posted this on the monkey2 forum.

I know this is more of a backend implementation but it would be awesome if we as developers could choose where to allocate our data (stack or heap). Currently all data that is not primitive is allocated in the heap and that is terrible for performance. I wouldn't force everything to be allocated on the stack but having the option would help a lot. Maybe add a keyword to specify that.
Like this
Local bar:Bar = Bar()
' Or
Local(stack) bar:Bar = new Bar()


Also it would be great if we could define the padding / alignment of our structures, class members and dynamic allocations.

Something like this.
Class Vec4
	Field(16) x:Float
	Field(16) y:Float
	Field(16) z:Float
	Field(16) w:Float
End

Local t:Foo = New(16) Foo()


Cheers,
Felipe


marksibly(Posted 2016) [#36]
I would love to add support for lower level stuff like this eventually, but it's unfortunately low priority right now.

Structs are already allocated on the stack, although arrays of structs aren't. However, I suspect what you're probably really after is structs of arrays, which is something I'd also love to do (and did think about a bit after it was first bought up) but, again, is low priority right now.

Still, an off-the-top of my head implementation could look like this:

Struct Entity
Field position:Vec3f Stream 0 'which 'array' this member goes in...could be named...?
Field velocity:Vec3f Stream 1
End

Local t:=New Vector<Entity>( 100 ) 'Vector means 'struct of arrays'...probably not the right name, but I don't like 'StructOfArrays<T>' either!

The data for a New<Entity>( 3 ) would then be layed out in memory like this:

position, position, position, velocity, velocity, velocity

We can't re-use 'normal' arrays here because the logical required to access element members is more complex - SOA's would need a table of 'pitches' or something similar that would need to be taken into account when accessing members.

Setting, getting elements would be a bit more complex (for the compiler at least) as members would need to be scattered/gathered when writing/reading.

The idea of the 'Stream' modifier for fields is for things like:

Struct Entity
Field position:Vec3f Stream 0
Field normal:Vec3f Stream 0
Field velocity:Vec3f Stream 1
End

...which would be layed out like:

position, normal, position, normal, position, normal...velocity, velocity, velocity...stream 2 stuff here...

All in all, it's a pretty major addition, but I think it's possible!

It's weird - structs of arrays is sort of how we used to do things WAY back in the struct-less BASIC days, eg: most games had something like this at the top:

Dim x(100),y(100),vx(100),vy(100)

Everything that's old is new again!


FelipeA(Posted 2016) [#37]
Thanks for the reply Mark!

This looks great. I understand this is really low priority but is nice to know that you have it in mind.
I know this is probably low priority too, but what about aligned allocations? Could this be a feature too? This is mostly to be able to write fast simd code. Working with unaligned memory usually has a bit of overhead.

Cheers,
Felipe


Danilo(Posted 2016) [#38]
MX2 is extendable, so you could write some functions like StackMalloc() and AlignedMalloc().
Maybe with ASM (different for different platforms) or C++ local byte-array[] with casting to void* pointer?
On Mac OS X the stack needs to be aligned, too.

AFAIK OS do already align memory allocations, and C++ compilers also do automatic struct alignment.
Changing struct alignment is probably different for different compilers (#pragma pack(1) or so), but something
like 'Struct Xyz Align 1' and 'Struct Abc Align 32' could be really useful, if possible with all different compilers.

See also Intel IPP, Intel MKL, etc. - such libs should be are useable with MX2. Just found Yeppp! - could also be interesting.


dmaz(Posted 2016) [#39]
Yeppp! sounds really fantastic but no ios support?


FelipeA(Posted 2016) [#40]
Implementing custom allocators would be ideal, but then it would be kind of a pain to handle monkey's gc. Maybe with an interface of some kind it and overloading the new.operator it could work.

OS does align memory, but usually depending on the size of the allocation. To take advantage of some functionallities allocations MUST be aligned at an especific value (16, 32, 64 bytes ...). I guess for now we could just focus on the most popular compilers like gcc, clang and msvc.

This is my cross compiler snippet for having alligned memory allocations:

#if _MSC_VER
	#define ALIGNED_MALLOC(size, alignment) _aligned_malloc(size, alignment)
	#define ALIGNED_FREE(p) _aligned_free(p)
// Assume we are running on Intel or AMD
#elif __GNUG__ && _WIN32
	#define ALIGNED_MALLOC(size, alignment) _mm_malloc(size, alignment)
	#define ALIGNED_FREE(p) _mm_free(p)
#else
	void* ALIGNED_MALLOC(size_t size, size_t alignment) {
		void* p = 0;
		posix_memalign(&p, alignment, size);
		return p;
	}
	#define ALIGNED_FREE(p) free(p)
#endif


This has work for me on msvc, mingw-gcc, arm-gcc, osx-clang and orbis-clang.


wiebow(Posted 2016) [#41]
New post on the MX2 blog!


Michael Flad(Posted 2016) [#42]
Maybe I misunderstand something but do we really need a special handling for this?

There's 2 primary performance related ways to layout memory - either struct of arrays or array of structs.

I guess basic arrays are there in Monkey so struct of arrays shouldn't be any issue at all?
Array of structs will be the more interesting part as it requires to access members of a struct within an array.
Given structs are value types the big question is probably if it's possible to access/modify structs in an array without making a full copy on the stack first. That's how it's done in C# and it's a crap way IMO. To modify an element in an array of structs I have to copy the element int a local value on the stack, do my changes and copy back the whole struct into the array.

AoS usually is something like
struct Entity{
float posX;
float posY;
float velX;
float velY;
};
Entity m_Entities[1000];

While SoA is
struct Entities{
float posX[1000];
float posY[1000];
float velX[1000];
float velY[1000];
};
Entities m_Entities;

Of course you can extend it into a struct of arrays of struct :)

struct vec{
float x;
float y;
};

struct Entities{
vec pos[1000];
vec vel [1000];
};

But that's just a combined version of the other two, we shouldn't need any special handling for this? The power of SoA is you can layout the memory the most efficient way you want to process it i.e. a single block of memory for the array elements you do some work on in a mostly sequential way or, in random access situations, you can limit it to the smallest possible block of memory so it fit's into the caches as good as possible.. But it doesn't matter if we have to allocate the arrays in the struct manually and if they're not all packed into one single block of memory - it's only important the elements within one of the arrays are in one continuous block of memory.


marksibly(Posted 2016) [#43]
Yes, it's possible to do all this manually, but it's a bit of a PITA to experiment with.

For example, you have to create 'substructs' if you want to have multiple values in a single stream, eg:

Struct posvel
vec pos
vec vel
End

Struct Entities
Field pv:posvel[1000]
Field img:Image[1000]
End

If you later want to 'move' either pos/vel to another stream, this all needs to change. You also need a new struct decl for each SOA 'type', which will also need to change when you want to add/remove/change stuff.

Thinking a bit more about this, there's no reason SOAs couldn't use the same syntax as normal arrays. Internally, the compiler could handle the difference, but since arrays can't be cast or anything weird, the compiler always knows exactly what type of array it's dealing with.

If all 'fields' go in stream 0 by default, then memory layout for a normal struct array and a SOA is exactly the same too!


Michael Flad(Posted 2016) [#44]
Ok now I get what you aim to do. Pretty cool and (afaik) unique idea.


marksibly(Posted 2016) [#45]
Actually, Jonathon Blow proposed something similar for his own language (he's got several videos on youtube) that got me thinking about this.

His approach was more complex (and powerful) but the idea is roughly the same.


wiebow(Posted 2016) [#46]
Anyone seen this?? https://github.com/blitz-research/monkey2
Compiler only release


DruggedBunny(Posted 2016) [#47]
Speaking of Jonathan Blow, I really liked his Defer thing, for automatic cleanup assistance on exiting a scope:

https://youtu.be/UTqZNujQOlA?t=1366

That would make stuff like stream handling so much easier in functions that might need to exit in multiple places.


Paul - Taiphoz(Posted 2016) [#48]
Watching that guys videos at the moment, he makes a lot of sense.


Danilo(Posted 2016) [#49]
> Anyone seen this?? https://github.com/blitz-research/monkey2
> Compiler only release

Yes, it was mentioned in the latest Patreon newsletter by Mark. ;)

BTW: Thanks, Mark!


impixi(Posted 2016) [#50]
Impressive so far!

I've ported some of my Monkey1 code to Monkey2, making use of the new language features where appropriate. Have been caught out a few times with casting issues (my own fault) and also concurrency conflicts when extending the provided container classes (also my own fault).

I haven't noticed any linking bugs yet by using the latest TDM-GCC compiler (5.1.02) but if I do I'll roll back to 4.9 as suggested.

To show my support I've donated via the blitzbasic.com "donate" button. Hope that's appropriate...


marksibly(Posted 2016) [#51]
> I haven't noticed any linking bugs yet by using the latest TDM-GCC compiler (5.1.02) but if I do I'll roll back to 4.9 as suggested.

The only bug I'm aware of is that it can't link windows format lib files, which means it can't link the angle libs required by windows GL. But if you're not using windows GL, 5.1.0 should be OK.

> extending the provided container classes (also my own fault).

The container classes aren't quite finished yet, but I'm pretty happy with the overall approach so the end result should be 'similar'. I'm devoting the next month to cleaning up and finalizing the language and standard modules (and adding a simple debugger) so it should be soon!

But of course please feel free to experiment and let me know what you think or if you have any ideas.

> To show my support I've donated via the blitzbasic.com "donate" button. Hope that's appropriate...

Awesome! Thank you very much!


GW_(Posted 2016) [#52]
(and adding a simple debugger)

Will this monkey2 debugger include globals like BMax? Plz say yes!


AnotherMike(Posted 2016) [#53]
I don't need any of the new language features but a real debugger would be priceless! :)


kmac(Posted 2016) [#54]
For those who are actively following development, if you have instructive or tutorial like examples, they would be most appreciated. I would contribute (e.g., patreon) to any serious effort to generate quality tutorials.


impixi(Posted 2016) [#55]
@kmac:

There's some good info written by Mark here:

http://monkey2.monkey-x.com/forums/forum/monkey-2-faqs/

I dig through Monkey 2's module source code to get an idea of how to use the not-yet-explained language features. It's time consuming but Mark's code is easy to understand, IMO.

Is there something specific you want to know about?

@Mark:

I spent about three more hours porting various code. I'm impressed at how solid the fundamentals are already. The only thing I've missed so far is a SizeOf operator, for the primitive types at least. Will the byte sizes vary depending on target or remain consistent?


kmac(Posted 2016) [#56]
@impixi

I don't have any particularly requirements. Though I support development I won't jump into the environment until some semblance of a primer or tutorial series exists - from novice to some advanced topics. From my perspective such documentation goes a long way to insure product survival, hence my willingness to contribute to the effort.


impixi(Posted 2016) [#57]
Nvm...


tiresius(Posted 2016) [#58]
If someone like impixi or Danillo who has already dived in could make a "Cheat Sheet" source file to show all the various MX2 syntax stuff that would be cool. I'd like to hit the ground running with MX2 and I find these references invaluable.


taumel(Posted 2016) [#59]
Assumption: If there will be a nice mojo3d/modern 3d, there also will be users and tutorials. Due to the feedback and Mark's posts i expect improved docs. Looking forward to an end user update. Btw. it's weird that news are spread via patreon/blog/twitter but not here. I wonder how far away gfx&sfx updates for monkey2 are, like, happening till 11/12.2016? When the industry will try to push VR.


marksibly(Posted 2016) [#60]
> The only thing I've missed so far is a SizeOf operator, for the primitive types at least.

There's one in libc, eg: libc.sizeof( blah ).

There may be one in the language eventually, but there are a few things to be considered first.

> Will the byte sizes vary depending on target or remain consistent?

They will remain consistent - see language quick ref for sizes of (in bits) built in types.


Danilo(Posted 2016) [#61]
libc.sizeof() can only be used with variables, and we need it for structs and types to do Alloc(.SizeOf(POINT) * 5 ), Alloc( SizeOf(Char) * 20 ) etc.


marksibly(Posted 2016) [#62]
Will do.

Tried to hack one together with this, but found 2 mx2cc bugs in the process...

Function Sizeof<T>:Int()
	Return libc.sizeof( Cast<T Ptr>( Null )[0] )
End


[edit]
Fixed! The above now works, eg:

Print Sizeof<Int>() '4!

Will git soon...


impixi(Posted 2016) [#63]
@tiresius

This isn't a "cheat sheet" source file but it might help you find your way to the interesting syntax.

For starters (assuming you already have monkey 1 installed to make use of its TED editor):

* Visit the monkey2 git repo. https://github.com/blitz-research/monkey2
* Download the monkey2-master.zip from the git repo.
* Unzip it to your root/home folder, rename the folder to monkey2.
* * Read and follow the instructions at the git repo. * *
* Load the hello-world.monkey2 file into monkey 1's TED editor. (It will recognize the MX2 syntax based on the .monkey2 file extension.)
* Run it to confirm everything is set up okay.
* NOTE: You'll need to install the relevent TDM-GCC if you haven't already.

Next:

* Read the Monkey2-quick-reference.html file (located in the monkey2 folder).
* Read the FAQs at http://monkey2.monkey-x.com/forums/forum/monkey-2-faqs/
* Load and run the tests in the monkey2\tests folder.
* Experiment!
* And remember that Monkey 2 is still in early development and things could change! ;)

Tip

* Early on, familarize yourself with the importing and namespacing mechanisms. There's a faq on it. Here's an incomplete list of the modules I've experimented with already:



databuffer.monkey2
std

filestream.monkey2
std

filesystem.monkey2
std.filesystem

filesystemex.monkey2
std.filesystemex

list.monkey2
std

map.monkey2
std

random.monkey2
std.random

stack.monkey2
std

std.monkey2
std




..

@Mark

Nice!


Danilo(Posted 2016) [#64]
Thanks, probably need to get used to Sizeof<Int>() and Sizeof<POINT>() syntax. ;)


marksibly(Posted 2016) [#65]
I saw that earlier comment!

Yes, it is a bit ugly, but there's a reason...

The '<Type>' syntax used by generics, Cast<T>, and the above Sizeof<T> etc is necessary partly because types need to be parsed differently from normal expressions, so you can't just make them 'normal' parameters, eg:

Function Sizeof( T:Type )
End

Print Sizeof( x(y) )   'hmmm...is the argument to Sizeof a result of invoking x(y), or is it a 'function type'? For that matter, is Sizeof( x(y) ) a function call or function type?


So '<Blah>' indicates to the compiler to parse 'Blah' as a type, not an expression.

C/C++ get around this simply by prohibiting 'forward references', eg: in the above example, if Sizeof is moved below Print Sizeof in the source code, it'll fail to compile. So in c/c++, whenever the parser sees a symbol it know whether it's a value, type, whatever.

But even if it wasn't necessary for parsing, I think it still makes sense to pass types in a different way 'first' because parameters can reference them, eg:

Function Blah<U,V>( x:U,y:V )
End

Here, '<U,V>' actually creates a little scope that the parameters can 'see' so I think it's clearer to have them separated out from normal parameters. Also, when you see <T> in source code, you know T is a type.

I'll probably still be adding a built-in Sizeof eventually that 'cheats' a bit and optionally allows you to pass (most) types as simple parameters, but Sizeof<T>() is really the 'right' way to do it. Ideally, sizeof should look pretty much the way it is: Sizeof:Int( Value ) and Sizeof<Type>:Int().


Danilo(Posted 2016) [#66]
With Macro’s your code would look like this:
Macro sizeof( _t_ )
    lib.c.sizeof( Cast< _t_ Ptr >( Null )[0] )
End

Macro’s don’t have a (return) type or something, because it is just text replacement. Macro’s are type-less.