Any news?
Community Forums/Monkey2 Talk/Any news?
| ||
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). |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
Having mx2 compile itself is a milestone. Congrats ! |
| ||
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. |
| ||
> 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! |
| ||
@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. |
| ||
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? |
| ||
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. |
| ||
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. |
| ||
@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... |
| ||
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. |
| ||
@Mark How are collisions handled (when using more than one, like in C#)? |
| ||
@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 |
| ||
Removed. I'm in doubt people (want to) understand what I'm trying to communicate openly. :( |
| ||
Nope, you're right but that's Mark. |
| ||
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. ?? |
| ||
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. |
| ||
> 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. |
| ||
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! |
| ||
>>> 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. |
| ||
> > 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. |
| ||
> 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. |
| ||
Posted this elsewhere but I guess can apply to MX2 as well, I was thinking something like this might be goodSelect 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. |
| ||
Eeek! What are you actually doing? |
| ||
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). |
| ||
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. |
| ||
> '? Else' and 'Extends Void' are in. Very nice, thanks! :) |
| ||
Here's one possible approach in monkey2: ... Sweet! |
| ||
I changed this because having to make every element of the 'literal' array the same type was silly/awkward. ah, totally awesome! |
| ||
@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'. |
| ||
> 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 ) |
| ||
I understand now, thanks for clarification! |
| ||
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 |
| ||
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! |
| ||
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 |
| ||
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 |
| ||
Yeppp! sounds really fantastic but no ios support? |
| ||
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. |
| ||
New post on the MX2 blog! |
| ||
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. |
| ||
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! |
| ||
Ok now I get what you aim to do. Pretty cool and (afaik) unique idea. |
| ||
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. |
| ||
Anyone seen this?? https://github.com/blitz-research/monkey2 Compiler only release |
| ||
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. |
| ||
Watching that guys videos at the moment, he makes a lot of sense. |
| ||
> 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! |
| ||
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... |
| ||
> 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! |
| ||
(and adding a simple debugger) Will this monkey2 debugger include globals like BMax? Plz say yes! |
| ||
I don't need any of the new language features but a real debugger would be priceless! :) |
| ||
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. |
| ||
@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? |
| ||
@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. |
| ||
Nvm... |
| ||
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. |
| ||
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. |
| ||
> 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. |
| ||
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. |
| ||
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... |
| ||
@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! |
| ||
Thanks, probably need to get used to Sizeof<Int>() and Sizeof<POINT>() syntax. ;) |
| ||
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(). |
| ||
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. |