Syntax wishlist/ideas

Community Forums/Monkey2 Talk/Syntax wishlist/ideas

Shinkiro1(Posted 2015) [#1]
Thought it might be good to seperate this from the language feature thread.
It's pretty clear that this is more of a personal taste debate so keep that in mind.

1)
Allow declaration of local variables without the use of the keywords local or field. This assumes that you can't redeclare your variables with it's type, which I don't see a reason to ever do.

Class Thing
  name:String
  position:Vector
End

edit: changed my mind, this is probably a bad idea. fine like it's in monkey1

Function Foo()
  x:Int = 20
  y:= 10.0
End


2)
Make comments start with //.
I know it breaks away from BASIC tradition but ' has to be the most unfortunate and unpleasing character to look at/type.


Skn3(Posted 2015) [#2]
- 1 million for locals without "local"

+ 1 million for comments tart with //


CopperCircle(Posted 2015) [#3]
Agree with Skn3 ;)


Nobuyuki(Posted 2015) [#4]
Make comments start with //.


yuck, no.


Danilo(Posted 2015) [#5]
Comments start with ';' or '//', simply because ' is a literal character identifier. Single-Quote ' =literal character, Double-Quote " = strings. Logical and easy.

Within (API) Structures, the 'Field' is unneccesary, I agreee.
Structure Point
    x:Int
    y:Int
End Structure

Structure PointF
    x:Float
    y:Float
End Structure

Such data structures simply don't have Global/Local/Static fields. It's just a definition/declaration of a memory structure/layout.


PixelPaladin(Posted 2015) [#6]
... but ' has to be the most unfortunate and unpleasing character to look at/type.

Well, it depends on the keyboard layout.
Personally I'm fine with basic ' or ; or pythons # or even luas --. But please don't use //.


Samah(Posted 2015) [#7]
-1 to both of these suggestions. I see no reason to change the existing syntax.


Skn3(Posted 2015) [#8]
-1 to both of these suggestions. I see no reason to change the existing syntax.

Would be nice if both ' and // were supported. So not remove the old syntax, just add an alternative.

I would say that because the main native language is cpp, and // is the defacto in cpp (as well as many other languages) it would be good to support this within MX2. As a module developer I have to deal with windows-keyboard/osx-keyboard, monkey, cpp, java, objc, javascript and c#... the common comment syntax across all of that (apart from monkey) is //, I can tell you that it is a common occurrence having to re-type typod comments. I am constantly having to readjust to the environment I am in at that particular time. // would take the edge off of this brain pain!


PixelPaladin(Posted 2015) [#9]
On a German keyboard layout ; # ' and – are absolutely easy to type but // is really painful. Since comments are something everyone uses very often it should be easy to input them. I think there are two possibilities now:

1. stay with ' because of monkey tradition

2. change single line comments so that they are more easy to type for everyone

C, C++, PHP, C#, Java and all the other curly brace languages have much more complex syntactic rules than just // for comments. They are completely different from monkey. I think it is a really bad idea to mix monkey with these languages and I am against multiple syntactic possibilities since it reduces monkeys consistency. It is right that // is a widely used standard in many programming languages – but there are others, too. Here are some examples for single line comments in other languages:

# python, perl, ruby, R, Tcl, LiveScript, Julia, Nim, Paren, racket, yaml

-- Lua, Haskell, Ada, purescript

% erlang, Matlab

; clojure, Lisp, Paren, racket, Red, whip, BlitzBasic

(see http://learnxinyminutes.com/ for more)

Some of these may support # as a second possibility since # is useful for scripting because of shebangs (#!/path/to/interpreter) but monkey already uses it for preprocessor directives. To use shebangs in monkey the preprocessor could simply ignore them. This would also allow monkey to become a nice scripting language in the future.
#!/bin/monkey

-- should be easy to type on most keyboards but I would prefer to stay with '.


Nobuyuki(Posted 2015) [#10]
if ya allow people to use more c-like syntax, they will use it. If it looks sufficiently foreign to Monkey/VB syntax, it will make code harder to read. So much more so if the styles are interchanged within the same document, as is the case when multiple coders work on something with no enforced style guide. Wiki seems to state that single quotes for comments are used almost exclusively by VB and RealBasic. I'm actually fine with this, because there is no precedent for using single quotes for char literals in VB -- we use the type sigil "c" for that, as in "a"c.

Type sigils have been used in BASIC forever, and I see changing comments to c-like // as part of a larger agenda to shove crap in there like single quote literals and other things of that nature which are "dependent" on each other once you start adding one or two of them in. Single quotes get used in some place other than for comments? Well, now it seems like parsing and lexing comments are more complicated, why not allow // comments for readability? Why not switch out the ' comment symbol entirely to avoid this? Etc. Next thing you know, we have another c-like language, because the people here who are more comfortable with that will be putting out code patterns which match this style and try to eschew BASIC syntax wherever possible. I've pointed out my philosophical opposition to this in previous threads, so I don't need to wade deep into it again, but nobody on the outside wants "yet another c-like".

Edit: I guess I'm not completely opposed to // comments "as an option", but I think it would be ugly, and more cruft. AFAIK, mx2 was going to remove some of that syntax flexibility that Monkey arguably had a bit 'too much of' in the first place. (Ironically, type sigils may have been one of those things?!)


MikeHart(Posted 2015) [#11]
Mark, for whatever you do, please don't make things optional. One way of doing comments, one way of ending a statement, etc etc. And if you choose a different langusge for It, please name it something else besides Monkey 2. As it won't be the successor but a new language.


taumel(Posted 2015) [#12]
a) variables definition like in C#, very elegant.
b) tabs indentation instead of ENDs, like in Python, so nice to read.
c) ' is great for single line comments, for multiple lines: '* *', easy to type and understand.


MaxPower(Posted 2015) [#13]
Class is a Type.(i think) cannot we leave it as Type (aka BlitzMax).Semicolons are bang on for COMMENTS.As a nested comment rem, end rem, WORK keep the basic nostalgia alive.


ziggy(Posted 2015) [#14]
a) variables definition like in C#, very elegant.
You mean substituting Local keyword by var keyword? Data type inference would require it, unless you do it like:
a:="Hello world"
Which can add considerable overhead to handle variables shadowing.


PixelPaladin(Posted 2015) [#15]
What about '[[ ... ]]'? I already use '* for inline documentation.
#rem and #end are also okay but should be case sensitive. At the moment multi line comments make syntax highlighting relatively hard to implement in some editors like gedit or notepad++ (they are case insensitive and #preprocessor commands at the same time).


taumel(Posted 2015) [#16]
@ziggy
A.o. i meant the definition (*1, just get rid of the ;) like, scope type name(s), it's clean, efficient and makes sense, no more finger breaking ":" or cryptic one character types. C#'s data types are nice too, ...

*1
private int i, j, k = 789;
Local i:Int, j:Int, k:Int = 789


Samah(Posted 2015) [#17]
This is just changing things for the sake of changing them. I've yet to see a convincing argument as to why any of this should change. Monkey syntax is 90% similar to BlitzMax anyway.

@Skn3: Would be nice if both ' and // were supported. So not remove the old syntax, just add an alternative.

Why? Adding alternatives creates personal preference and makes code inconsistent between developers.
As it is, optional semicolons irk me to no end. If I'm modifying other developers' code, OCD kicks in and I don't know whether to use semicolons or not, or whether to go through and add or remove them all.

@Nobuyuki: If it looks sufficiently foreign to Monkey/VB syntax, it will make code harder to read.

This. I love my braces and semicolons, but after years of using Monkey/BlitzMax I've come to the conclusion that they don't belong.

@MikeHart: Mark, for whatever you do, please don't make things optional. One way of doing comments, one way of ending a statement, etc etc.

Exactly.

@taumel: b) tabs indentation instead of ENDs, like in Python, so nice to read.

Begin and End blocks instead of tab indentation, so nice to read.

@taumel: c) ' is great for single line comments, for multiple lines: '* *', easy to type and understand.

I wouldn't be entirely against this, but I wonder if something like triple quotes might be better.
'''
multiline
comments
'''


@MaxPower: Class is a Type.(i think) cannot we leave it as Type (aka BlitzMax).

Except classes are classes in just about every other OO language.

@ziggy: You mean substituting Local keyword by var keyword? Data type inference would require it, unless you do it like:
a:="Hello world"

Which means the developer needs to pay attention to that extra character that says "this is declaring a local variable with an inferred data type" rather than a clear keyword, and "Local" is fine.
@ziggy: Which can add considerable overhead to handle variables shadowing.

Yep.

@PixelPaladin: What about '[[ ... ]]'? I already use '* for inline documentation.

Inline documentation should be generated with an external tool based on the content of comment blocks, and should be seen as just a regular comment block to the compiler.
Javadoc and Doxygen both use /**, C# doc tool uses ///

@PixelPaladin: #rem and #end are also okay but should be case sensitive.

#Rem and #End are keywords, and like all other keywords in Monkey they should be case insensitive.

@PixelPaladin: ...relatively hard to implement in some editors like gedit or notepad++...

Then use another editor. Syntax highlighting is incredibly difficult in languages with preprocessor commands, since the IDE needs full control over the toolchain to get it right.
Example:
#If FOO="bar"
#Rem
Print "hello"
#Else
Print "world"
#End
#End

FOO could be defined in another file or on the command line, so there's no way to tell which part is and isn't comments.

@taumel: no more finger breaking ":" or cryptic one character types. ... private int i, j, k = 789;

Which moves completely away from the standard way of doing things in Monkey and BlitzMax, and will completely break any backward compatibility.


taumel(Posted 2015) [#18]
I don't care about backwards compatibility. Isn't Monkey with Mojo2 going to be updated for those who can't let things go?

I do care about a new language i might enjoy using and how it could be done the best.


Samah(Posted 2015) [#19]
@taumel: I don't care about backwards compatibility.

And you're entitled to not care, but there are plenty of others who will.
@taumel: Isn't Monkey with Mojo2 going to be updated for those who can't let things go?

It's not about "letting it go", it's about migrating existing Monkey code to Monkey 2. Developers are much more likely to embrace it if there are minimal changes required to make their old code compile with the new language.
@taumel: I do care about a new language i might enjoy using and how it could be done the best.

As do I, but ignoring the cost of migration is a surefire way to put people off. If it's going to take me weeks/months to port my code to Monkey 2, and I don't need any of the new features, why bother? If I can port my code in a few days with minor tweaks, that's fantastic.


PixelPaladin(Posted 2015) [#20]
@Samah: Inline documentation should be generated with an external tool based on the content of comment blocks, and should be seen as just a regular comment block to the compiler.


I am using an external tool which I have written. It uses '* comments in monkey documents and writes a *.monkeydoc file.

The #Rem example looks pretty interesting. I did not know that nesting rem blocks is possible.


taumel(Posted 2015) [#21]
@Samah
I wonder what plenty actually means.

If core concepts of a language aren't changed then migration often is quite easy. And nope, i don't consider such vars def as a biggy.

I think the benefits of a 'better' language/tool are far more important for its future than the migration costs of some/a few projects.


Nobuyuki(Posted 2015) [#22]
@samah: I wouldn't be entirely against this, but I wonder if something like triple quotes might be better.


Using it to open/close a REM block actually sounds interesting to me; perhaps it would be easier for web / notepad parsers to handle? It's not entirely unheard of -- VB.NET uses triple quotes for tags, but each line must begin with '''. VS makes this easier by recognizing tag blocks in the IDE. It may also possibly make autodocumentation easier, though it seems like the way that currently works is to have a separate file for documentation and code.

+1 to keeping var declarations the way they are. Don't mess with it, they make so much sense the way they are now; Newbies are forced to understand how scoping works through the declaration keyword, and scope ambiguity is practically eliminated when skimming a block of code, even someone else's code from a distance. The only thing that "doesn't" make sense from my BASIC background is Global, and that is due to my preconditioning to believe that Global means GLOBAL no matter where it lies, and this is not very OO-friendly. It makes more sense to a newbie that Global inside a class means Static/Shared. The only other language I can think of off the top of my head that "gets this" is Ruby, and Ruby is 1. dynamic and 2. uses sigils, so it's not directly comparable. But just like Ruby, in typical style patterns, it's dead easy to figure out what belongs where.
Edit: May have misinterpreted the conversation. I'm okay with getting rid of type sigils, even though it's a "BASIC tradition". It would make the code more readable. The varname:Type syntax is fine the way it is, and works identically to AS3, with the major exceptions being that Monkey is more strongly-typed and also requires declaration with the appropriate scoping keyword.

I'd believe what Samah said about people wanting change "for change's sake" with little convincing to back up those radical changes, but I feel like it's more like an agenda. One that's been laid to rest several times already, which makes me wonder why it's cropping up again now...

@taumel: I think the benefits of a 'better' language/tool are far more important for its future than the migration costs of some/a few projects.


I've yet to see these benefits, personally...


Samah(Posted 2015) [#23]
@taumel: I wonder what plenty actually means.

It means more than just one person's opinion.

@taumel: If core concepts of a language aren't changed then migration often is quite easy

Changing a large codebase to Python-style indentation is non-trivial.

@taumel: And nope, i don't consider such vars def as a biggy.

I do, so we'll have to agree to disagree.


marksibly(Posted 2015) [#24]
I wont be removing Field or Local, partly for the migration issues, but also because I think it's part of what gives monkey its 'personality'. Which probably sounds like BS to some people, but I like the amount of consistency monkey enforces here - it's part of what makes monkey monkey. Hard to describe...

On a semi related note, I've also been thinking recently about how to treat keyword case - upper or lower? - and for now I'm going with monkey1 style, ie: keywords are case-insensitive, so IDE's can auto-capitalize if they want. This isn't 100% finalized, but it will be this way for V.01 at least.

I had been using lowercase keywords up to a few days ago, and that's OK and all, but I recently got around to hacking Ted up a bit so tried out the monkey1 style first off - and I reckon it just plain reads better.

With the explicit decls and uppercase keywords, Monkey is sort of self-documenting. Perhaps this is what it means to be BASIC-like?

Anyway, I got some pretty interesting stuff going recently, including:



...and...



I'm trying hard for a weekend 'reward' release, although it'll be as fragile as hell!

Still, it's getting to the point where the language itself is *almost* usable! Still 1001 non-language things to deal with, but it's getting there.


Skn3(Posted 2015) [#25]
Oooo operators...

Oooo structs...

Oooo better generics...


marksibly(Posted 2015) [#26]
Actually, pretty much same generics, just using a function type!


therevills(Posted 2015) [#27]
Wish: Newline has no effect on program execution.


taumel(Posted 2015) [#28]
I've just written two pages of code in a Monkey style and in a style with changes i've mentioned before (plus a few others). The first one is cumbersome and looks kind of outdated, the second one is clean and a joy to read and write.

I don't want to code in monkey2 if one of its major goals is to reimplement the sins of monkey (even more as monkeys' user base is way too small to make possible migration issues a relevant point). In my opinion Mark is wasting an opportunity to create something better, also for a bigger audience due to wrong decisions.

Maybe Mark's suggestion was right that i'm probably more interested in a zebra than a monkey 2. Out of curiosity i will stick around to check out the first release but depending on this one and possible information available where he wants to go from there on, i might step away from this project as i currently don't have a good feeling that it will end up like something i want to use, on platforms which are important to me (thinking of html5), ...

Anyway good luck and looking forward to the first release.


Samah(Posted 2015) [#29]
@therevills: Wish: Newline has no effect on program execution.

+1


marksibly(Posted 2015) [#30]
> Wish: Newline has no effect on program execution.

You mean compilation?

This means though that either statement separators are optional (which I thought everyone hated) OR all lines must end in ";" (which I at least hate).


DruggedBunny(Posted 2015) [#31]

Wish: Newline has no effect on program execution


"Why?" would be my first question!


GW_(Posted 2015) [#32]
"Why?" would be my first question!

Agreed, "why?"
I've also been thinking recently about how to treat keyword case - upper or lower?

Definitely 'case-insensitive' It's not good to only rely on the ide's to handle this, It's low hanging fruit imo.

Also Mark, when you release the first alpha, there are going to be a ton of spurious 'bug' reports. Have you thought about how that should be handled without cluttering up the Monkey2 forum topic? It's bound to get messy.


dmaz(Posted 2015) [#33]
over loaded operators!!! yay!! that is so awesome. I also like how the function type looked. but, what the diff between a Struct here and a Class?

+1 to Field, Local

re: newline no effect on execution...
yes, why? I actually liked optional statement separators.
required ; are crap.

@taumel, lets see that code comparison.

I'm with you when asking; why worry about compatibility when designing the base of this new language? The only real concern should be creating something that is modern, efficient and easy to understand... One shouldn't be held back by yesterdays decisions especially with this small base. Not to mention it should take less then a few days of coding to write a conversion app. That said, I generally like Mark's languages so I still want them to feel mostly the same. I'm totally on board with dropping "End" completely though!

and bah on worrying about how an ide handles case insensitive keywords, they've been doing it for decades. I'm with Mark, case sensitive small case keywords don't read as well as upper camel. though I only type them lower case which is why it's the perfect solution!


Danilo(Posted 2015) [#34]
What's the difference between Struct and Class in MX2?

Struct Point
    Field x:Int
    Field y:Int
End


Class Point
    Field x:Int
    Field y:Int
End

And how does this integrate with the ptr / varptr pointer-level access, exactly?
Local pt1:Point         = New Point()
Local pt2:Point ptr     = New Point() ' ?
Local pt3:Point ptr     = varptr pt1
Local pt4:Point ptr ptr = varptr pt2  ' ?



marksibly(Posted 2015) [#35]
Ok, think I've come up with a pretty good solution to the newline/split lines issue: basically, newline is ignored EXCEPT when the compiler expects to a see an 'end-of-statement' token ie: ";", at which point newline will be accepted as an end-of-statement.

There will be exceptions, eg: things like single line Ifs still need to take newlines into account, but for most code it should make newline 99% irrelevant.

> What's the difference between Struct and Class in MX2?

Struct objects are allocated on the stack, and are always passed/copied 'by value', eg:

Local v1:Vec3=new Vec3
v1.x=0
Local v2:=v1
v2.x=10
Print v1.x    'prints '0' - if Vec3 were a class, would print '10'.


You can currently Varptr a struct but not a class. This gives you a pointer into the stack, which is dangerous but very useful for extern APIs, eg:

	Local e:SDL_Event
	While SDL_PollEvent( Varptr e )<>0
		If e.type=SDL_QUIT
			Print "Received SDL_QUIT event"
			SDL_DestroyWindow( window )
			window=Null
			Return
		Endif
	Wend


Eventually, there will also be a way to allocate structs on the heap (which will also return a Ptr).

Structs are very fast to allocate and don't require GC (although their members might), but come at the cost of some additional copying (although sometimes this is good). I wasn't going to attempt operator overloading without them, as the overhead of creating temporary class objects (which need full GC) for expressions like v1*v2+v3 is just too great.


MaxPower(Posted 2015) [#36]
Hi is there no easier way you can close,Methods and Functions,instead of using End.


marksibly(Posted 2015) [#37]
> Hi is there no easier way you can close,Methods and Functions,instead of using End.

I have no problem with End myself - any ideas?


Danilo(Posted 2015) [#38]
From what I understand, I have to create 2 separate Structs and Classes now - for every structure!

One for use Stack-based, one for use pointer-based.
Struct sPoint
    Field x:Int
    Field y:Int
End

Class cPoint
    Field x:Int
    Field y:Int
End

I'm speaking about thousands of API structures. Basically every structure needs to be duplicated, one for stack & one for pointer use!?

I hope it's a joke!?

Pleasing the "ignore-newline" people creates an even bigger mess.
Local a:Int, b:Int

If a = 1
    ' doIt()
End If
b = 2

Local c:Int, d:Int

If c = 1
    ' doIt()
End If d = 2

Local e:Int, f:Int
    
If e = 1
    ' doIt()
End
If f = 2
End If

Sorry! I get the feeling it was a mistake to spend any money on a project that's still not well-thought-out.
You can't please everyone, I know. But currently it looks like a mess to me, trying to please everyone.


skid(Posted 2015) [#39]
Varptr on Structs? Nice!


Samah(Posted 2015) [#40]
@marksibly: I have no problem with End myself - any ideas?

End is fine.

@marksibly: Ok, think I've come up with a pretty good solution... *snip*

I just made a huge post elaborating on this with examples, but then I read your reply.
@marksibly: ...but for most code it should make newline 99% irrelevant.

Perfect. :)

@marksibly: ...things like single line Ifs still need to take newlines into account...

To be honest I hate single line Ifs. Now that newlines are optional, maybe there could be a compromise where you just need to put the End keyword in.

In Monkey 1:
If foo Then bar()

Is essentially the same as:
If foo Then
	bar()
End

Which leads me to say, why couldn't you just have single line Ifs like this?
If foo Then bar() End

That gets rid of newlines in yet another situation.

@Danilo: Pleasing the "ignore-newline" people creates an even bigger mess.

Actually, it makes the language much more elegant, because the syntax is now much stricter. If it fails compilation it's because your code is wrong, not just that you have a newline somewhere you shouldn't.


therevills(Posted 2015) [#41]
@marksibly On a semi related note, I've also been thinking recently about how to treat keyword case - upper or lower?

I would keep the whole language consistent, if variables etc are case-sensitive make keywords case-sensitive (lowercase).

@marksibly: ...but for most code it should make newline 99% irrelevant.

99% perfect.

@marksibly: I have no problem with End myself - any ideas?

What else would you use instead of End? Braces? End is fine for me too.


Danilo(Posted 2015) [#42]
Samah wrote:
Actually, it makes the language much more elegant

I am not sure I want to pay $360 / year for such a mess.
Reminder: What I want to spend on a voluntary basis (every year) is already much more than I paid for Monkey1,
with free life-time updates.
Make keywords fixed to be lowercase (WHY?) and I'm out of that ugly mess.... everyone can fork it anyway, for free.


Samah(Posted 2015) [#43]
@Danilo: I am not sure I want to pay $360 / year for such a mess.

Not quite sure how you got "mess" from "elegant"...

@Danilo: Reminder: that's already much more than I paid for Monkey1 with free life-time updates.

Reminder: Patreon is an optional donation. Monkey1 was mandatory for mobile targets. You're free to pay $0 for it if you choose.

@Danilo: Make keywords fixed to be lowercase (WHY?)

Actually I agree with you here. Basic-ish languages have a history of case insensitive keywords, and I see no reason to change it.

Edit:
I notice you've edited your post a lot there, specifically the part about voluntary donations. Generally replies will go AFTER the post.


therevills(Posted 2015) [#44]
@Danilo - Make keywords fixed to be lowercase (WHY?) and I'm out of that ugly mess.

@Samah - and I see no reason to change it.

I already stated the reason, for consistency. Another would be it would be easier to write IDEs etc.


Samah(Posted 2015) [#45]
@therevills: Another would be it would be easier to write IDEs etc.

if token == "class" then keyword

if token.toLower() == "class" then keyword

...


Danilo(Posted 2015) [#46]
IDE's can have style options to write/replace "endif" / "EndIf" / "endIf" / "eNdIf". We are talking about the language itself here, not about any IDE's.


therevills(Posted 2015) [#47]
@Danilo "eNdIf"

And you said you were "out of that ugly mess."....


Samah(Posted 2015) [#48]
@Danilo: IDE's can have style options to write/replace "endif" / "EndIf" / "endIf" / "eNdIf". We are talking about the language itself here, not any IDE's.

Exactly. If it were really a problem, Visual Studio, #Develop, Blide, Jungle, and others would be unusable.


Danilo(Posted 2015) [#49]
therevills wrote:
And you said you were "out of that ugly mess."....

Yes, I am awaiting Mark's answer, not reacting in a rush. The "duplicating structs and classes" thing was my biggest concern
when seeing it first time.


Samah(Posted 2015) [#50]
Mark:
Can structs have methods, like in C++? From an implementation standpoint, I don't see why they couldn't.


DruggedBunny(Posted 2015) [#51]

I am not sure I want to pay $360 / year for such a mess.


Kinda knew a minority would use threatened withdrawal of donations to try and force their own preferences. (You don't have to pay $360/year, by the way.)

I prefer capitalised keywords and capitalised (BRL) function/method names. Not going to throw all my toys out of the pram if Mark makes another call, though.


PixelPaladin(Posted 2015) [#52]
@Danilo: This "duplicating structs and classes" thing is part of C#, too – and there are reasons for that. It does not mean that everything has to be duplicated.


Samah(Posted 2015) [#53]
Regarding keyword case-sensitivity, I really don't care. I'll just use it how it's designed.
If there had to be a decision, I'd prefer all lowercase.


therevills(Posted 2015) [#54]
I prefer capitalised keywords and capitalised (BRL) function/method names. Not going to throw all my toys out of the pram if Mark makes another call, though.


Mark asked for opinions and I gave mine - and I'm happy to listen to others too as long as dummies aren't spat.

Regarding case-sensitivity as a whole, I prefer it and I know some are against, some have changed their mind after user Monkey. I guess it depends on what market/mind-set Mark is aiming MX2 at....


Samah(Posted 2015) [#55]
@PixelPaladin: This "duplicating structs and classes" thing is part of C#, too...

I don't see this as a problem really, because most of the time you'll only want one or the other. If it's something that needs to be passed around as an object, you'll define it as a class. If it's something that needs to be passed around as a value, you'll use a struct.
If you want to pass a struct "by reference" as you would a class, use a pointer.


Danilo(Posted 2015) [#56]
To use a structure as both, stacked-based and pointer-based, it seems you have to declare them twice.
Even C++ is easier to use: Point x; vs. Point* y;. In MX2, it seems, you have to duplicate ten-thousands of structures!?


Samah(Posted 2015) [#57]
@Danilo: To use a structure as both, stacked-based and pointer-based...

I don't see why you would want to explicitly put a struct on the heap. With your point example:
Struct Point
	Field x:Int
	Field y:Int
End

Function Foo()
	Local pt:Point ' stack
	pt.x = 1
	pt.y = 2
	PassAsValue(pt)
	PassAsPointer(VarPtr pt)
End

Class Sprite
	Field position:Point ' heap, because Sprite is a class
	Field size:Point ' heap, because Sprite is a class

	Method Foo()
		Self.position.x = 1
		Self.position.y = 2
		Self.size.x = 10
		Self.size.y = 20
	End
End


@Danilo: Even C++ is easier to use: Point x; vs. Point* y

Except that's not a value type, which is the point of structs.


Nobuyuki(Posted 2015) [#58]
for single line ifs, require Then.

I also don't understand how removing the need for newlines is considered elegant. You can write bad looking code with this. Can someone explain it to me like I'm 5? I'm not going to lose my cool over it, I am just wondering why several people seem to think it's a good thing.

As for keywords.... I think they should be case-insensitive. Keep variables case-sensitive but if keywords "need" to be case-sensitive too, please make them Sentence Case. Modern BASIC follows this convention of re-capitalizing all keywords in this fashion, even though I believe it's case-insensitive, too.

Operator overloading is exciting!


marksibly(Posted 2015) [#59]
> for single line ifs, require Then.

I am leaning towards this - plus only one statement after the then. That way you can skip the 'End' and don't need any special case end-of-line checking.

> I also don't understand how removing the need for newlines is considered elegant.

I try to keep everything on one line myself, but there are times when you're calling something with a ton of parameters where I do think spitting lines is a better alternative than ending up with lines that are too long to view in your editor, so I sort of get it. I also think it'll be a more important issue the more libs monkey2 embraces, some of which have pretty complex APIs, eg: IMO, CreateWindowEx is more readable with a line for each parameter.

In the long run, it's not a huge deal to me but it's something a fair number of people want and that I do think is theoretically useful so I'll try my best to do it well!

> Operator overloading is exciting!

Isn't it! Freaked myself out when that Vec3 code first ran...!


ImmutableOctet(SKNG)(Posted 2015) [#60]
I haven't been keeping up with these threads very much, but I don't think Danilo is on the same page. You're basically getting pointers, which work with structures no less. And better C and C++ interoperability. And since pointers to structures aren't useful without a way to modify said structures, I imagine "dereferencing" will be a thing. Keeping this in mind, you already have the ability to use structs like C, you just don't implicitly get garbage collection. I imagine structs will have destructors of some kind, so object references in structures wouldn't be an issue, then.

I agree that being able to use a class on the stack would be useful, but the entire point of structs is that they're small objects that don't take more than a cache line. Objects on the heap are generally the same way, but they have the benefit of never being copied (In Monkey's garbage collection terms). The biggest issue I can see with not having stack-allocated classes is C++ libraries (STL, mainly) which do that. But, if structures have methods anyway, Monkey could treat those types as structs.


Samah(Posted 2015) [#61]
@marksibly: I am leaning towards this - plus only one statement after the then.

Sounds good, but people need to realise that you can't use Else on the same line any more.
These are equivalent:
If foo
	If x > 10 Then x = 10 Else x = 2
End

If foo
	If x > 10 Then x = 10
Else
	x = 2
End



therevills(Posted 2015) [#62]
@Samah - These are equivalent:

And imagine if people dont indent their code!!
If foo
If x > 10 Then x = 10
Else
x = 2
End



dmaz(Posted 2015) [#63]
oh, I missed the new For loop format the first time through the 2 examples... nice!

yeah, I often have 2 statements after an if / then, so I wouldn't like only allowing 1 but I'd get over that.


marksibly(Posted 2015) [#64]
> oh, I missed the new For loop format the first time through the 2 examples... nice!

That was initially meant as a placeholder until I got the 'real' loops going, but I think it's very useful and am considering leaving it in.

> yeah, I often have 2 statements after an if / then, so I wouldn't like only allowing 1 but I'd get over that.

Same here, and as Samah points out we'd lose 'Else' too. Still thinking this one over...


therevills(Posted 2015) [#65]
Same here, and as Samah points out we'd lose 'Else' too. Still thinking this one over...

Just enforce an "End" at the end, its clean and simple :)


Danilo(Posted 2015) [#66]
Samah wrote
These are equivalent:
If foo
	If x > 10 Then x = 10 Else x = 2
End

If foo
	If x > 10 Then x = 10
Else
	x = 2
End


It's only the same if you ignore newlines. It's ambiguous in this case.

In the first example, the Else is for the If [Expression] Then [Statement-list] Else [Statement-list].
In the second example, the Else is for "If foo".

[Statement-list] are multiple [Statement] separated by comma:
If x > 10 Then x = 10, y = 20 Else x = 2, y = 30


You just need an Optional:Bool(token) method in the parser:
' => If [Expression]
If Optional(tkThen)
    ' Single-Line
    Eat(tkThen)
    list1 = ParseStatementList()
    If Optional(tkElse)
        Eat(tkElse)
        list2 = ParseStatementList()
    End
    Expect(tkNewline)
    return new SingleLineIfStatement(list1, list2)
Else
    ' Multi-Line
    Expect(tkNewline)
    block1 = ParseStatementBlock()
    If Optional(tkElse)
        Eat(tkElse)
        Expect(tkNewline)
        block2 = ParseStatementBlock()
    Endif
    Expect(tkEndIf)
    return new MultiLineIfStatement(block1, block2)
EndIf

(Simplified, because there can be multiple ElseIf cases, too)

So, we don't loose [Else], because it is on the same line - in a single-line If-Statement.
In a multi-line If-Block, the Else is on a separate line.

Separated keywords (keywords that consist of more than one word) in MonkeyX can create ambiguity,
especially when ignoring newlines: "If" "End" -> "If" "End" "If" "Else" "If" ...
    Local a:Int, b:Int
    
    If a = 1
        ' doIt()
    End If
    b = 2

    Local c:Int, d:Int
    
    If c = 1
        ' doIt()
    End If d = 2

    Local e:Int, f:Int
    
    If e = 1
        ' doIt()
    End
    If f = 2
    End If

Multi-Word keywords like "Else If", "End If" are a problem. No problem with "ElseIf" / "End" / "EndIf"...

- http://www.monkey-x.com/Community/posts.php?topic=9713&post=102173&page=1
Danilo wrote (2 month ago):
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]




Nobuyuki(Posted 2015) [#67]

> oh, I missed the new For loop format the first time through the 2 examples... nice!

That was initially meant as a placeholder until I got the 'real' loops going, but I think it's very useful and am considering leaving it in..


I'm totally okay with c-style For syntax, as long as I can keep BASIC / Monkey style-- "Until" is the best thing since sliced bread and totally fixes the "weird" way you'd always have to adjust bounds for loops to not go over by 1 using To. C-style syntax is pretty versatile if we're still gonna have that limitation that forces the Step value to be known at compile time...


GW_(Posted 2015) [#68]
Agreed, Options are good, but definitely keep the old style 'for-until' too


DruggedBunny(Posted 2015) [#69]

I'm totally okay with c-style For syntax, as long as I can keep BASIC / Monkey style-- "Until" is the best thing since sliced bread


"Like"


Shinkiro1(Posted 2015) [#70]
Options are good

Only if they enhance functionality.
Alternative syntax to achieve the same thing will make code harder to read, less consistent and confuse new users.


Samah(Posted 2015) [#71]
@Danilo: It's only the same if you ignore newlines. It's ambiguous in this case.

That was the whole point of my example. If we completely ignore newlines, it brings in that ambiguity. This is one of the reasons I dislike single-line if statements.

As therevills points out, if you still use the End keyword, it turns the single-line if into a regular if block, but listed all on one line. All problems go away. Adding End to your example:
If foo
	If x > 10 Then x = 10 Else x = 2 End
End

Is the same as:
If foo
	If x > 10 Then
		x = 10
	Else
		x = 2
	End
End

Which is exactly what we're after.

Your examples are all assuming that we keep newlines as part of the syntax, and the possibility of dropping them is the whole point of this discussion.

@GW_: ...Options are good...

To a degree. Once you make too many things optional, it starts to get messy with each developer of a project having their own style.

@Shinkiro1: Only if they enhance functionality.

Exactly.


Gerry Quinn(Posted 2015) [#72]
I don;t think being value types was ever really the point of structs. Allocating on the stack was the point, because in Java and C# like languages instances normally were allocated on the heap, which often led to inefficiency. Then treating them as value types fitted in with the language.

Consider C++ in which classes and structs exactly the same (except for the default access qualifier). Because in C++ you control exactly how everything is stored and referenced anyway...


Danilo(Posted 2015) [#73]
Samah wrote:
Which is exactly what we're after.

Class cls Abstract Public Method a:Int() End Method Method b:Int() End Method End Class
Function fun() Local foo:Int, x:Int If foo Then If x> 10 Then
x = 10 Else x = 2 End
End

I see what you want. It's the opposite of what other users want (the newline-based guys).

Statement separator ; should act exactly like newline, except it does not increment line numbers. With that, we could join lines (without any ambiguity):
While x; x -= 1; Wend
Unfortunately it has problems with the If-Statement in MX1:
If x; x = 0; End
If foo; If x > 10 Then x = 10  Else  x = 2; End
If foo; If x > 10 Then x = 10; Else; x = 2; End
Doesn't work like expected with other constructs, though:
Class cls Abstract; Public; Method a:Int(); End Method; Method b:Int(); End Method; End Class


Gerry Quinn wrote:
Consider C++ in which classes and structs exactly the same (except for the default access qualifier). Because in C++ you control exactly how everything is stored and referenced anyway...

That's what I thought. But maybe we can control that with structs: x:Point VS. x:Point ptr = Mem.Alloc()


PixelPaladin(Posted 2015) [#74]
The current idea for single line if statements would be longer than the normal case:

If True Then Foo("bar")
If True Foo("bar") End


I think it would be the best to enforce 'End'. There would no longer be a problem with newlines acting the same as other white spaces and since function calls without parentheses are no longer allowed we exactly know where statements begin and where they end:

If True
    Foo("bar", "hello", "world")
End
Foo("bar", "hello", "world")

' Putting two things on one line is no problem:

If True Foo("bar", "hello", "world") End Foo("bar", "hello", "world")

' Splitting lines is also not a problem:

If True
    Foo (
         "bar"
         ,"hello"
         , "world"
        ) End
Foo("bar",
    "hello",
    "world"
   )



Here is an other idea for syntax simplification:
we could relinquish ',' like in lisp:

Foo("bar" "hello" "world")
Local a:Int[] = [1 2 3]
Local b:IntStack = {1 2 3}          ' my idea from the curly braces topic since I think
Local c:IntMap<Int> = {1:2 3:4 5:6} ' Mark will not read it because of the headline ^^


Edit:
I forgot some key words, sorry ...


Nobuyuki(Posted 2015) [#75]
I also don't understand how removing the need for newlines is considered elegant. You can write bad looking code with this. Can someone explain it to me like I'm 5? I'm not going to lose my cool over it, I am just wondering why several people seem to think it's a good thing.


Is it more elegant in the way the internal code handles it? Ignoring newlines on operators seemed fine the way it was... Please, again I ask for an explanation. This is starting to make If syntax seem a bit contrived by BASIC standards...


therevills(Posted 2015) [#76]
For me, ignoring newlines makes more sense and logical. Yes you can write some bad looking code with it but least it is consistent, but again you can write some really bad looking code with newlines being part of the syntax (especially if you dont indent your code).

Have a look at some of the examples which PixelPaladin above have posted, to me its cleaner.

This is starting to make If syntax seem a bit contrived by BASIC standards...

Its only one more keyword at the end of a single line IF, not that much contrived IMHO :)


Samah(Posted 2015) [#77]
@Danilo: I see what you want.

No, that's not what I want at all. By "what we're after", I was referring to how the logic in the two examples are identical.

@Danilo: Statement separator ; should act exactly like newline, except it does not increment line numbers. With that, we could join lines (without any ambiguity):

My point is that the grammar should be designed in such a way that semicolons and newlines have no effect on the flow whatsoever. The compiler would be smart enough to know that the preceding keyword is the end of the statement.

If you want to enforce semicolons as line splitters to make:
Class cls Abstract Public Method a:Int() End Method Method b:Int() End Method End Class

Look like:
Class cls Abstract; Public; Method a:Int(); End Method; Method b:Int(); End Method; End Class

Then that's your decision. A good programmer would not do that, so it's a moot point.


Danilo(Posted 2015) [#78]
Samah wrote:
If you want to enforce semicolons as line splitters to make:
Class cls Abstract Public Method a:Int() End Method Method b:Int() End Method End Class

Look like:
Class cls Abstract; Public; Method a:Int(); End Method; Method b:Int(); End Method; End Class

Then that's your decision.

In a line-based syntax, the first is not allowed. Each statement is on a separate line, and such languages
usually have a line-joiner / statement-separator (':' or ';' in our case). The lexer/tokenizer returns the same
token for end-of-line and the statement-separator then (for example tkEndOfStatement), with the difference
that the separator does not increment internal line number count.
With this implementation in a line-based language you can put multiple statements on one line, separated by the
statement-separator. You can join any line/statement then. Currently this works only for some statements.

MX1 looks like a mix of both styles (line-based with ';'-separator works only in some cases, and continuous input stream is also limited.)

People asked Mark to fix it and make it more strict (line-based with ';' separator). He agreed and probably coded it already.
2 month later some people request the opposite now, asking to remove everything and make it a continuous input stream.
Even other guys want line-based statements with Tab-dependent indention, removing all 'end' statements.

Different people want different styles. It probably explains the mix in the resulting language.

I think it is better to decide for one style, and make clean, consistent syntax rules. At the end, you can write nearly
the same code with either style. In one case everything is a continuous input stream, in the other case
statements are clearly separated by end-of-line and the statement-separator ';'.


therevills(Posted 2015) [#79]
@Danilo - People asked Mark to fix it and make it more strict (line-based with ';' separator). He agreed and probably coded it already.

Could you please provide a link for this?

I think it is better to decide for one style, and make clean, consistent syntax rules.

For once I agree with you ;)


ziggy(Posted 2015) [#80]
Regarding the parser:
A sentence needs to be parsed token by token. If a EOL appears in the middle of a expression, the parser can continue doing its job, so you can have things like parameters separated in several lines. In the other hand, if the parser finds that after an expression is being completely parsed there's not a statement separator neither an EOL, then a syntax error is thrown. This way you have a consistent mix of both things. That's what I've understood reading Mark posts carefully. There are already some languages that do parse like this, and it allows for a very nice syntax.


Danilo(Posted 2015) [#81]
@therevills:
Did you miss that part? It is not a simple link, it's many things that were discussed month ago.

Just look at Mark's reaction in the current thread, page 2:
> Wish: Newline has no effect on program execution.

You mean compilation?

This means though that either statement separators are optional (which I thought everyone hated) OR all lines must end in ";" (which I at least hate).

He clearly seems to be surprised that someone is now asking for the opposite of what was discussed before.


Playniax(Posted 2015) [#82]
I am a little late to the party here but I am reading all of this and I guess at the end of the day I just trust Mark to make the right design decisions.

I wouldn't like to much drastic changes though, only if it improves functionality or performance if possible!


Samah(Posted 2015) [#83]
Danilo, what you're essentially saying then is that you want a language where statements must be explicitly separated by either a newline or a semicolon. I'm saying that it should be designed such that you need neither, and the compiler is smart enough to know what you want.

@Danilo: He clearly seems to be surprised...

Let's hear from the man himself before we second guess him.


GC-Martijn(Posted 2015) [#84]
Maybe someone could create a online poll/survey https://support.google.com/docs/answer/87809?hl=en
with all the options that are possible to get some indication what people want.
there are now several topics with al kind off things.

My english is not good enough to create a overview survey.


Danilo(Posted 2015) [#85]
Samah wrote:
Danilo, what you're essentially saying then is that you want a language where statements must be explicitly separated by either a newline or a semicolon.

Yes, it is what I generally think - for a language like MonkeyX 2. It's not only me, though. I had the feeling it was a general agreement/consensus
within the community, when we discussed it. Examples from BlitzMax and MX1 were discussed.
There was no contract, no final statement. More a feeling that most agree, and Mark basically said to make it more strict.
After that was clear, additional wishes came to allow line continuation at operators/separators (that presupposes statements/lines end at EOL).
MX2 is in the working. 80%+ from MX1 is ported. Parser is more strict. Some additional (new) features are also working already.

That's my personal summary, after following the discussions and Mark's postings over the last 2 or 3 month. :)


therevills(Posted 2015) [#86]
Danilo, I think you are assuming a lot and reading into things in a totally different view than me...

Well let's see what happens and hope that MX2 is the best thing since sliced bread :-)


dmaz(Posted 2015) [#87]
Danilo is right about previously discussing enforcing the ; for separators. I think it started with some talking about the Monkey 1 style being inconsistent and something should change. Either fix it or go back to enforcing the ;. This was probably more than a month ago and Mark seemed to indicate (I'd find it but search is kinda broken) he'd go the way of making it stricter even though it was a pretty short discussion. Later though, python style was suggested which I think started up the conversation again with a larger audience. (that's how I remember it anyway, but I'm old so I could be completely wrong)

My view is... going back to enforcing the ; as a separator is the wrong direction. Monkey 1 style is way better than being stricter. If it can be made more "consistent", then even better. That said, the python style looked good to me in most cases, but then I wrote a short program in it and didn't like it as much but that might be that I'm just not use to it for longer programs.

I for one don't like ending all Ifs with End...
To fix that why not just have Then mean only 1 statement follows unless they have a strict separator. something like the , that was suggested or why not a ;
Basically the ; just puts the statement in the last block. We don't need them for anything else now right? Else would still need to be closed with End though of course

[edit] I wrote some test code... never mind, just require End is the answer especially since the word is shorter that Then.


Danilo(Posted 2015) [#88]
therevills wrote:
Well let's see what happens and hope that MX2 is the best thing since sliced bread :-)

Yep. Currently I have a good feeling. At the current state, basic decisions hopefully don't get changed too radically anymore. :)

Only stuff I would like to know (and is not that clear atm) is, is it still possible to import JavaScript libs with the emscripten stuff?
Beside that, most things should be pretty clear from all the discussions. For the remaining few unclear things it's probably okay
to just think positively. ;)

First release shouldn't be that far away anymore. Although the more interesting Import stuff
will take a little bit more time. *impatiently waiting*

My wife's 40th birthday party starts in round about 3 hours, with many of her Thai girlfriends and some of the other husbands,
so I'm out of the discussion anyway (and not in the mood). :D


marksibly(Posted 2015) [#89]
Well, I'm kind of surprised at how contentious all this is! I'll try and explain where I'm going with this...

There are really 2 things going on here that I want to achieve. First, I want monkey2 to be stricter about decl/statement separators, so you can't just run things together like:

a[b]=10 print( c ) d=20

...which works in monkey1, but has bitten me on the bum several times. So now you need to go:

a[b]=10 ; print( c ) ; d=20

I *hope* we can at least agree this is a good thing? Ok, just read Samah's comment...maybe not then!

The second (related) thing is to decide how monkey2 deals with line splitting, ie: where newlines can be safely ignored. I do want to allow this somehow because, while I don't do it a lot myself, in certain situations I think it is very useful.

Due to the 'stricter separators' rule above, just ignoring newlines altogether is out because then you'd have to finished each line with a ";" which ain't gonna happen.

Monkey1 deals with this by allowing newlines after a bunch of 'special' tokens, like "+", "-" etc but I've never been particularly happy with this approach. I mean, you can split after a "+" but not before - what's up with that?!? It's just a bit archaic for my liking. Furthermore, people were always wanting more characters included in the 'special' tokens list - but it was getting harder and harder to prove to myself what could be safely added to the list. Part of this is no doubt due to the lax statement separator situation in monkey1, but regardless, I've always felt the 'special list of tokens' approach was kind of hacky.

So monkey2 currently works by ignoring newlines *except* where an 'end-of-statement' is expected, which kind of complements the strict statement separator rule above (and of course, you can't have "~n" in the middle of identifiers/keywords etc).

IMO this is a simple, easy to remember rule that allows people to split things pretty much however they want. If you think that's bad, I respectfully disagree.

Some examples:

The syntax for a normal 'block if' is currently something like:

IfStmt="if" Expr <eos> StmtBlock { ( "elseif" | "else" <nbsp> "if" ) Expr <eos> StmtBlock } [ "else" <eos> StmtBlock ] ( "end" | "endif" | "end" <nbsp> "if" ) <eos>

(Note: I could/might remove the <eos> after the "else", but I want it there after the 'if' expr to prevent expr stmtblock running together).

Some notes about this syntax:

| means alternatives.
{ } means '0 or more of'.
[ ] means '0 or 1 of'.
<eos> means a sequence of ";" and/or "~n" tokens (newlines are ignored elsewhere).
<nbsp> means whitespace that does NOT contain any newlines - necessary to keep compound keywords like "Else If" from confusing things.

So a block like this:

If x=0
   Print( "A" )
Else If x=1
   Print( "B" )
Else
  Print( "C" )
Endif


...can also be written like this...

If x=0 ; Print( "A" ) ; Else If x=1 ; Print( "B" ) ; Else ; Print( "C" ) ; Endif


...a simple one liner written this way isn't too bad I guess, but I think I will still add special syntax for one liners. Going by my own code, and the code in bananas, short ifs are very frequently used.

The syntax for a class decl is something like:

ClassDecl="class" Ident [ "extends" Type ] [ "implements" Type { "," Type } ] { "abstract" | "final" } <eos> ClassDecls ( "end" | "end" <nbsp> "class" ) <eos>

So, yes, you *can* write a class like this:

Class
Blah
Extends
Poo
End


...but 'don't do that'. And if we find this flexibility is causing problems, we can slip extra <nbsp>'s into the syntax.

Anyway, if all this sounds too complex/messy, ignore it and keep writing code the way you did in monkey1, it should work!

This is stuff is kind of messy, but I think that's mainly because I'm trying to formalize a lot of stuff that was done very informally in monkey1.


EdzUp(Posted 2015) [#90]
TBH I would get the base language out first then worry about everyones coding styles after all its faffing around trying to please everyone that causes long lags in release times.


PixelPaladin(Posted 2015) [#91]
Note: These are some suggestions I wanted to make before I saw Marks Post – it seems this is no longer needed...

Here a suggestion for what I think could be an acceptable solution for most of us (at least I hope so):

Enforcing parentheses makes monkey2 strict enough that theoretically we could handle line breaks same as other white spaces. The transpiler knows where statements end. The downside of this is that single line if statements must be closed.

Semicolons should also be possible to separate statements. It helps in a visual way to see, where a statement ends:

Foo(a, b, c) Bar(x, y, z)
Foo(a, b, c) ; Bar(x, y, z) ' better readable


Best would be to have both possibilities:

1. handle newlines like other white spaces. This allows us to separate parameter lists and arrays anywhere we want, which helps us formatting code in a readable way.

2. handle semicolons like a whitespace, too. This helps writing (and reading) single line statements:

If 1=1 Foo(a, b, c) Bar(x, y, z) End
If 1=1 Foo(a, b, c) ; Bar(x, y, z) End ' looks better


For better readability we could also have optional keywords like Then, Endif, Next, EndFunction...
But it is important that closing keywords must be ONE word: "EndMethod" but not "End Method"
(theoretically "End Method" would be possible, too, but it could be problematic to debug a source code where you forgot to close a statement).

Method Foo:Void(a:Int) ; If a=1 Then Print("Foo") Endif ; EndMethod


All in all this would still be really strict if you think about it – but at the same time it brings more freedom compared to monkey1.
Plus: the rules itself are simpler because there are no special rules for single line statements anymore. This way it is also easier for the monkey transpiler.

Here some comparisons for single line statements:

' handle semicolons as newline
Method Foo:Void(a:Int) ; If a=1 ; Foo(a, b, c) ; End ; Bar(x, y, z) ; End ' too many semicolons

' ignore line breaks (no semicolons):
Method Foo:Void(a:Int) If a=1 Foo(a, b, c) End Bar(x, y, z) End ' hard to read

' handle line breaks AND semicolons as separator:
Method Foo:Void(a:Int) ; If a=1 Foo(a, b, c) End ; Bar(x, y, z) ; End ' better

' optional keywords make it even easier to read:
Method Foo:Void(a:Int) ; If a=1 Then Foo(a, b, c) Endif ; Bar(x, y, z) ; EndMethod ' even more readable



Gerry Quinn(Posted 2015) [#92]
I thought the way Monkey1 works with regard to allowing newlines after certain operators was quite satisfactory. It wasn't my original style (in C++ I liked to put the operator first on the next line) but I soon got used to it and didn't find it limiting.


therevills(Posted 2015) [#93]
@Mark: Well, I'm kind of surprised at how contentious all this is! I

We are programmers! And that makes us contentious about the little things ;)

@Mark: IfStmt="if" Expr <eos> StmtBlock { ( "elseif" | "else" <nbsp> "if" ) Expr <eos> StmtBlock } [ "else" <eos> StmtBlock ] ( "end" | "endif" | "end" <nbsp> "if" ) <eos>


So in MX2 "end", "endif" and "end if" are still valid (and I guess "end", "endmethod" & "end method" etc)? Again just my opinion I would just have one and not three end statements (just "end")..


Danilo(Posted 2015) [#94]
Just 'end' for everything, removing the possibility to use 'EndIf' and 'Wend'?
(You are able to use 'end' for everything, even if other users still can use the alternatives)


Samah(Posted 2015) [#95]
@marksibly: So monkey2 currently works by ignoring newlines *except* where an 'end-of-statement' is expected, which kind of complements the strict statement separator rule above (and of course, you can't have "~n" in the middle of identifiers/keywords etc).

This is EXACTLY how I was hoping it would work. Awesome! :D

@Danilo: Just 'end' for everything, removing the possibility to use 'EndIf' and 'Wend'?
(You are able to use 'end' for everything, even if other users still can use the alternatives)

Actually I'm totally fine with keeping all of these "End"-ish keywords (End, EndIf, EndMethod), just get rid of the dual token "End If" and "End Method", etc. All they do is make it harder to grok.
I have a feeling this is kinda what you're after too, but I could be misreading it.


GW_(Posted 2015) [#96]
just get rid of the dual token "End If" and "End Method", etc. All they do is make it harder to grok.

I use these types of tokens all the time (and like it). Bmax handles them, Monkey1 handles them. Unless it creates ambiguities in the new parser, why change it?


therevills(Posted 2015) [#97]
Unless it creates ambiguities in the new parser, why change it?

It creates ambiguities in users, sometimes too much choice is bad.


GW_(Posted 2015) [#98]
It creates ambiguities in users, sometimes too much choice is bad.

of those with limited groking abilities maybe. ;-)


Danilo(Posted 2015) [#99]
Samah wrote:
I have a feeling this is kinda what you're after too, but I could be misreading it.

End:
It is a nice shortcut. I use it mostly for ending Function / Method / Class.

ElseIf / EndIf / Wend / Next / EndSelect ('EndSelect' is missing):
Special ending keywords for control flow (choice, loops, ..). I like it, and use it.
For those, I don't like to use just 'end': If...End, While..End, For...End

End Something (separated by Space):
Personally I can live without it. I think it is for users coming from VB-compatible BASICs,
because many of those BASICs use "End If", "End Function".


Nobuyuki(Posted 2015) [#100]
@marksibly: There are really 2 things going on here that I want to achieve. First, I want monkey2 to be stricter about decl/statement separators, so you can't just run things together like:

a[b]=10 print( c ) d=20

...which works in monkey1, but has bitten me on the bum several times. So now you need to go:

a[b]=10 ; print( c ) ; d=20

I *hope* we can at least agree this is a good thing? Ok, just read Samah's comment...maybe not then!


Well, I thought it was a good idea, which is where my doubts/confusion about ignoring newlines in particular came from in the first place! Now that you've explained it all, I'm a lot more comfortable and confident that how you're handling it in mx2 is probably a good way to go. VB handles lines very strictly, and only allows splitting using an explicit line separator (there is no line concatenator character). Even then, there are restrictions to how a line can be split. So the way it sounds like MX2 is going to handle it seems a lot more elegant.

Yes, I suppose the thing I was most worried about would be people going full "reducio ad absurdum" with the terseness and removing things like explicit line concatenators to satisfy some unexplained urge to create awful lines like "a[b]=10 print( c ) d=20". I've seen previous threads on this forum where people have had trans basically blow up in their face due to doing something like this, specifically with the single line If syntax when Then is omitted. I was having trouble understanding why anyone would want to have the ability to do more of this.

@pixelpaladin:
For better readability we could also have optional keywords like Then, Endif, Next, EndFunction...
But it is important that closing keywords must be ONE word: "EndMethod" but not "End Method"
(theoretically "End Method" would be possible, too, but it could be problematic to debug a source code where you forgot to close a statement).



I hope Mark keeps allowing us to use the style of ending blocks verbosely, because this is my personal style and it helps improve readability. (Jungle does the hard work of typing out the blocks for me.) As Danilo hinted towards, this is how VB does things, and I personally think it increases readability, particularly for those times when a code block goes off screen (and don't get snippy, everyone knows it happens, even to 'disciplined' coders!)

I don't mind the shorter syntax, but I will totally fight the people trying to "End" the verbose way if it's already available :)


PixelPaladin(Posted 2015) [#101]
@Nobuyuki: […] to create awful lines like "a[b]=10 print( c ) d=20"


I get your point but what I tried in my last post was to bring everything from the previous posts together to a small set of simple rules. What people actually want is not to write code like in your example but to have more possibilities to write cleaner code. You can also write unreadable code in monkey1, right?

The only real downside of my suggestions was that it would not be compatible with the "End Xyz" syntax but only with "End" and "EndXyz" – so it would not be compatible with monkey1 (like python3 is not compatible with python2 code).


therevills(Posted 2015) [#102]
@Nobuyuki: I don't mind the shorter syntax, but I will totally fight the people trying to "End" the verbose way if it's already available :)

Let's dance! :)

@PixelPaladin: so it would not be compatible with monkey1 (like python3 is not compatible with python2 code).

Not a bad thing IMHO. Sometimes to move forward we need to leave things behind.


Skn3(Posted 2015) [#103]
A use case argument for /* */ comments.

As #rem and the #preprocessor currently have a shared closing keyword (#end) it is impossible easily to block comment out the following:
Function TestFunction:Void()
	Local something:= 1
	#IF BLAH = 1
	#ELSE
	#End
	Print "waa"
End


Currently we would have to do this:
#rem
Function TestFunction:Void()
	Local something:= 1
	#IF BLAH = 1
	#ELSE
	#End
	#rem
	Print "waa"
End
#end


Which is fuggly and awkward. If we had /* */ we could just do this:
/*
Function TestFunction:Void()
	Local something:= 1
	#IF BLAH = 1
	#ELSE
	#End
	Print "waa"
End
*/



GC-Martijn(Posted 2015) [#104]
@skn3
I vote for that !
Its like my previous topic about braces/bracket whatever the name is haha, less characters is more overview.
I know its a personal feeling, but every 'then', and 'end' less is better reading for me.


Nobuyuki(Posted 2015) [#105]
Still prefer ''' (3 or more apostrophes beginning a line) to open/close blocks of comments to /* */, as it has a close analogue in VB's annotations system and is easier to type.


therevills(Posted 2015) [#106]
Still prefer ''' (3 or more apostrophes beginning a line) to open/close blocks of comments to /* */, as it has a close analogue in VB's annotations system and is easier to type.


I prefer /* */ as I think my eye sight it slowing getting worse and ''' is pretty hard to read...


Samah(Posted 2015) [#107]
I like the idea of sticking with apostrophes, tbh:
' single line
'* multi
line *'



dmaz(Posted 2015) [#108]
+1 '*
I like that quite a bit actually


Skn3(Posted 2015) [#109]
'* is a good compromise

It is definitely harder to see then /* but if it was '* vs #REM then I think its probably obvious which would win!


Nobuyuki(Posted 2015) [#110]
A variant on the null coalesce operator from C# has been introduced to both C# and VB in 2015 called the null conditional operator.
https://msdn.microsoft.com/en-us/library/dn986595.aspx

Essentially what it does is it short-circuits member and array access operators. Meaning that if you replace a member/array access operator with the appropriate null conditional operator, it will return Null on the first null and not attempt to process any further accesses in the chain. This is great for tidying up code, making it easier to write safer code (and less tempting to omit safety checks out of laziness!).


nullterm(Posted 2015) [#111]
In 20-30 years, I think everything will be null safe by default, just the way languages seem to be evolving. Programmers will look back on us as cavemen for creating programs that could die over something so trivial. haha

The guy who invented null in the 60's apologized for doing so in 2009. https://en.m.wikipedia.org/wiki/Tony_Hoare


Leo Santos(Posted 2015) [#112]
Another (possibly stupid) idea:
How about a ReadOnly feature that sets fields as read only when called from outside the class.

For instance, this:
Private

Field _width:Float
Field _height:Float									
Field _x1:Float, _y1:Float, _x2:Float, _y2:Float
Field _pivotX:Float = 0						
Field _pivotY:Float = 0							

Public

'************  Read only fields  **************

Method width:Float() Property; Return _width; End
Method height:Float() Property;	Return _height;	End
Method x1:Float() Property; Return _x1; End
Method x2:Float() Property; Return _x2; End
Method y1:Float() Property; Return _y1; End
Method y2:Float() Property; Return _y2; End
Method pivotX:Float() Property; Return _pivotX; End
Method pivotY:Float() Property; Return _pivotY; End


Would be simplified to this:
Public
Field width:Float				ReadOnly
Field height:Float				ReadOnly
Field x1:Float, y1:Float, x2:Float, y2:Float	ReadOnly
Field pivotX:Float = 0				ReadOnly
Field pivotY:Float = 0				ReadOnly


You'd still be able to write the value from within the class.
Cheers!


Nobuyuki(Posted 2015) [#113]
Leo: I think auto-implemented properties would address this, but so far mark has taken a bit of a conservative approach to properties in mx2 and hasn't changed them much from monkey in either syntax or functionality afaik. I wonder if the cost overhead of such a ReadOnly directive would make fields just as expensive to access as a Property representing it...


Leo Santos(Posted 2015) [#114]
Got it.

Would it be too unsafe to make it a compile time thing? Example: If you mark it as read only and then try to write it, Monkey would throw an error before translating, but the field would "technically" be read/write in the translated C++ code. Sounds dangerous, but would have no performance hit. Anyway, I'd be Ok with a small performance hit if the code is more compact like that.

Cheers!


ImmutableOctet(SKNG)(Posted 2015) [#115]
There's no real performance hit from most properties to begin with, especially not really basic ones. There's only the potential for branching problems when using what are effectively "virtual" calls. Which, in the case of most properties, shouldn't be an issue. Properties are in-lined on most targets, and the ones that don't in-line the call aren't much of an issue anyway.

Either way, if we were to get a "ReadOnly" keyword, it would need to be handled at compile-time, without a property. On x86 and x64, there's no such thing as "read only" safety within your own program, it's just semantic. Even if you were to wrap access to a field, write access is still available to any code at user-level. Because C++ gives you control of memory, this means you shouldn't bother. Just follow standard practice, and respect memory boundaries, even if they're sometimes fake.

The big bonuses (Other than people feeling their designs are better) are thread safety (As well as playing well with cache) and better defining expected behavior. This is why C and C++ have 'const'. Monkey's basically the opposite about how access works. You don't get const-references, you get openly mutable objects. So, following this pattern, we really do need an "externally immutable" keyword. In Monkey currently, you can do this with 'Protected' and 'Private' properties. And since they don't have any real overhead, they're not an issue. But, they are annoying to write every time you need something to be immutable.

To put it simply, we really do need something like this, even if it's just better property syntax. And it shouldn't be implemented using code generation, that's just a hack that'll cause runtime errors. There's no need to implement a "getter" method either, this is evaluable at compile-time.

Sorry, just felt like going on a bit of a tangent. I agree with Leo Santos's sentiment, "ReadOnly" isn't a bad idea.


Samah(Posted 2015) [#116]
As long as developers have the ability to make advanced getters/setters that do more than just provide magic encapsulation for a field.
For example, I might want a getter to do an advanced calculation and cache it, then return the cache on future calls.
I might even want a setter to do something like firing off property change events, or have the ability to veto the property change if it's an invalid value.


GW_(Posted 2015) [#117]
What you're asking for is 'Immutable' variables, and if implemented, it should be done for all datatypes everywhere, not just class fields. There are performance and safety benefits to immutable variables. but It's not the same a 'const' type which can be altered via it's pointer.


ImmutableOctet(SKNG)(Posted 2015) [#118]
@GW_: You can't modify something that is 'const' in C and C++, unless you manually use a static cast (Or similar) to do so. Other than access qualifiers (Public, private, etc), C++ keeps everything mutable, and uses 'const' references (Usually just pointers anyway) or pointers to handle things that are immutable. What Leo Santos was getting at was not simply immutable types/variables (Which don't really exist on user-level x86 anyway, DEP aside), but instead the equivalent of wrapping a variable in a property. Still mutable from the class/struct, but not from outside of it. There's a number of benefits for this, most notably reducing boilerplate, and giving better rules around thread-safety. I'll admit, having fully immutable structs and/or classes would be pretty nice, though. But following the spirit of Monkey, I think classes should be mutable by default, at the very least. By the way, didn't Mark say something about making structures immutable at one point? That would be pretty cool, albeit a little backwards. An interesting idea would be different "remote access" behavior for each by default. I still honestly like the idea Monkey's had for a while; things are mutable or immutable based on individual contents. With C++, it's all-in hierarchically, which has its benefits. But at the same time, those benefits can still be had with proper usage of selective mutation.

Whatever the case may be, I like the idea of 'ReadOnly'. It would be purely about the variable itself, not the referenced object. The object's class(es) would dictate what's mutable, and it's up to the developer to handle what's publicly (im)mutable, and why. It's an interesting twist on it, if you ask me. Coming from game development roots, Monkey's always been about data manipulation first. After all, the default access qualifier is 'Public'.


marksibly(Posted 2015) [#119]
How about just using 'Property' for 'read only'? eg:

Class Color

   Property Red:Float        'read=public (or protected if in a protected block etc), write=always private
   Property Green:Float
   Property Blue:Float
   
   Method New( r:float,g:Float,b:Float )
      Red=r
      Green=g
      Blue=b
   End

End


You can still do 'smart' properties...

Class Color

   Property Red:Float()
       Return _r
   Setter( r:Float )
      _r=r
    End

   Private
   Field _r:float...

End


Note: 'Setter' is just an idea right now, but I think it's the least 'ugly' way to do blocks of property code (still pretty ugly though IMO). There'd also be Getter so you could write properties in a variety of ways, eg:

Property Red( r:Float )
   'setter only
End

Property Red:Float()
   'getter only
end

Property Red:Float() 
   'getter
Setter( r:Float )
   'setter1 
Setter( r:Blah )
   'setter2
End

Property Red( r:Float )
   'setter1
Setter( r:Blah )
   'setter2
Getter:Float()
   'getter
End


...or we could drop 'Getter' and make it so if a property has a getter, it has to appear first.


Samah(Posted 2015) [#120]
@marksibly: How about just using 'Property' for 'read only'? eg:
'read=public (or protected if in a protected block etc), write=always private

No, because that's not what the definition of a property is.
https://en.wikipedia.org/wiki/Property_(programming)

I like something like this:
Property Foo:Float() Get ' generates default getter, doesn't generate a setter
Property Bar:Float() Set ' generates default setter, doesn't generate a getter
Property Hello:Float() ' no code generation
Property World:Float() Get Set ' generates default implementations for both getter and setter

' manually define a setter
Property Foo:Void(value:Float)
	blah = value + 10
End



marksibly(Posted 2015) [#121]
> No, because that's not what the definition of a property is.

That definition includes: "...or read-only 'fields'...", so it seems fine to me.

Also, the lack of () indicates to me that no code is generated - the public read/private write thing is purely semantic (which it is). In code, it's just a field.

> Property Foo:Float() Get ' generates default getter, doesn't generate a setter

What does the default getter 'get' though? ie: how does a setter write to it? via: Foo=blah? In which case, no code is generated, it's just a field.

Also, not too keen on stealing Set and Get keywords...Getter and Setter I can live with.


therevills(Posted 2015) [#122]
What about:
Property Foo:Float()
	Get:Float()
		Return blah
	End
	Set:Void(value:Float)
		blah = value + 10
	End
End



Samah(Posted 2015) [#123]
@marksibly: That definition includes: "...or read-only 'fields'...", so it seems fine to me.

It includes it, but's it not restricted to it, which is what your initial statement implies. Maybe I misunderstood it.

@marksibly: What does the default getter 'get'? ie: how does a setter write to it? via: Foo=blah?

Property definitions in C# are a pseudo-field that you define read and write accessors. The value is part of the property. Monkey's current Property keyword is just a way of replacing method calls with field access syntax, which isn't really a proper analogy (though still very handy).

@marksibly: Also, not too keen on stealing Set and Get keywords...Getter and Setter I can live with.

I only suggested Get/Set because that's what it is in C#.

Edit:
@therevills: What about:

I had originally thought about something like that, and it's pretty nice. There's not really any reason to define variable types on the Get and Set methods though, since it's declared at the top level.


nullterm(Posted 2015) [#124]
ReadOnly seems pretty low on the radar.... to me. But a good feature for down the road.

I think a combination of Private and a Property get function in existing Monkey language is pretty straightforward.

I like this existing properties operate, as well. Although substituting "Method X:Float() Property" for just "Property X:Float()" suits me just fine, anything the makes code smaller.



Just my opinion.


marksibly(Posted 2015) [#125]
> What about:

Not bad, but I think I still prefer the shorter:

Property Foo:Float()

      Return blah

Setter( value:Float )

      blah=value

End


> Maybe I misunderstood it.

I meant it as a shortcut for "Field blah:int Readonly" - it wouldn't replace 'functional' properties, just complement them.


marksibly(Posted 2015) [#126]
> ReadOnly seems pretty low on the radar.... to me.

I think I would actually find this quite useful myself, as I (try to) write a lot of immutable classes and these would be great for that.


ImmutableOctet(SKNG)(Posted 2015) [#127]
@marksibly: Sounds good to me. I definitely like the idea of using the 'Property' keyword in-line, instead of adding another one. As for the normal property syntax you mentioned, would it support multiple input-types? Because that, and the lack of extra arguments when using it as a method are the only problems I could see with it. But I could live without the latter, since I could just wrap a method with it anyway. And the former isn't used very often anyway, but would be useful to override something like implicit type-conversion.


Nobuyuki(Posted 2015) [#128]
marksibly said: Note: 'Setter' is just an idea right now, but I think it's the least 'ugly' way to do blocks of property code (still pretty ugly though IMO). There'd also be Getter so you could write properties in a variety of ways, eg:
...
...or we could drop 'Getter' and make it so if a property has a getter, it has to appear first.


I'm still totally partial to specifying properties in this way. Making the "getter" block not require an explicit keyword is kinda "meh" to me (I guess I just like the "flash card"-like appearance to requiring both), but I wouldn't mind the omission since the syntax you proposed seems pretty close to my "ideal" preference. Requiring specifying the Getter can help future-proof Properties against having to implement a default behavior in the case of generic types where you may want type-specific return behavior, as would be in the case when creating "magic" properties that can run a specific getter as needed without an explicit cast. I don't think there are too many situations where people would want a write-only Property anyway, but food for thought I guess?

Also, not too keen on stealing Set and Get keywords...Getter and Setter I can live with.

+1



ImmutableOctet(SKNG) said: Sounds good to me. I definitely like the idea of using the 'Property' keyword in-line, instead of adding another one. As for the normal property syntax you mentioned, would it support multiple input-types? Because that, and the lack of extra arguments when using it as a method are the only problems I could see with it. But I could live without the latter, since I could just wrap a method with it anyway. And the former isn't used very often anyway, but would be useful to override something like implicit type-conversion.



Exactly. Having a Getter keyword allows for multiple getters, and requiring one protects against having to come up with a default backwards-compatible behavior in the future should 1. one need not be specified now, and 2. multiple getters end up being something that is implemented in the future. But, I don't mind being able to omit the keyword, if this doesn't seem like it would be a problem down the road.


itto(Posted 2015) [#129]
I'd like to have a specific keyword to denote a read-only thing, so that it could be used both for struct or class fields, and function parameters (like "const" in C++). Something like this could also force for example a struct to be read-only only in determinate functions. It's something which could help a lot in creating expressive code and less hassles. I'd like to see many compile-time features like this, they are cheap and help you catch errors early.


Nobuyuki(Posted 2015) [#130]
Please make Shr/Shl do what they actually imply, and add operators for Sal/Sar which preserve the sign bit explicitly instead of relying on the implementation's interpretation of >> on whether this preserves the sign bit. Signed/Unsigned type handling sounds like it's still in the air, but at the very least we can resolve this ambiguity. Regardless of whether people have access to unsigned types, when directly altering the bits at least we can explicitly choose whether or not to respect the sign bit.

(From what I understand, currently Shl ignores sign bit, whereas Shr preserves the sign bit.... ugh!)


Danilo(Posted 2015) [#131]
> (From what I understand, currently Shl ignores sign bit, whereas Shr preserves the sign bit.... ugh!)

That's correct for signed numbers, see Arithmetic shift.

SHL shifts to the left and fills the new position (least significant bit) with a 0.
SAR shifts to the right and fills the new position (most significant bit) with the old MSB.


Nobuyuki(Posted 2015) [#132]
That's correct for signed numbers, see Arithmetic shift.

SHL shifts to the left and fills the new position (least significant bit) with a 0.
SHR shifts to the right and fills the new position (most significant bit) with the old MSB.


Is that so? I don't know x86 assembly (or any assembly language, for that matter), but that seems to break the mnemonic. SAR = Shift Arithmetic Right ? If SAR preserves the sign bit, then you would think that SHR would move the sign bit, ignoring the datatype (if assembly even has these constructs....). Are you saying that the operation depends on the datatype? What is the operation to shift right and ignore the sign bit for signed numbers, then?

My original point was that having these operators around, and changing their functions from the Monkey1 way for mnemonic consistency, could alleviate some problems and sidestep at least one issue related to requiring unsigned datatypes in mx2 (not to imply that they're unnecessary or anything). One other alternative would be to use the c-style operators instead of assembler ones.


Danilo(Posted 2015) [#133]
SAR = Shift Arithmetic Right = Signed Numbers = Shift Right and preserve the sign bit (Most significant bit, MSB)
SHR = Shift Right = Unsigned Numbers = Shift Right and fill the MSB with 0
SAL = Shift Arithmetic Left = Signed Numbers = Shift Left and fill the least significant bit (LSB) with 0.
SHL = Shift Left = Unsigned Numbers = Shift Left and fill the least significant bit (LSB) with 0.

SAL and SHL are the same, and there is a difference between SAR and SHR.

- http://x86.renejeschke.de/html/file_module_x86_id_285.html
- https://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate
- http://docs.oracle.com/cd/E19455-01/806-3773/instructionset-27/index.html


Nobuyuki(Posted 2015) [#134]
So then, one more time. For mnemonic consistency, I think it would make more sense to change it for mx2 to reserve sign-bit preserving operations to SAL/SAR, and sign-bit ignoring operations to SHL/SHR.


Danilo(Posted 2015) [#135]
Does it make mathematical sense to do a signed bit shift to the left, and overwrite the
most significant bit with the old MSB? Outside your imagined Monkey world, shift left
always seem to mean the sign-bit is lost, when shifted to the left (see SAL & SHL).

I think you want a signed shift left, where only the lower 7, 15, 31, or 63 bits are
shifted to the left, and the sign bit stays the same. That's how I understand your texts.
How does this make mathematical sense, in the world of two's complement, etc.?
If the rest of the world doesn't do it that way, it doesn't seem to be required in a
mathematical sense.


Nobuyuki(Posted 2015) [#136]
mainly, my concern is for shift right, not shift left. So, I'm not going to argue for the practical usefulness of shift left. It is a distraction to my earlier point, which is that the current mnemonic doesn't make sense. Don't hang your hat on the practical usefulness of an arithmetic shift left when it's disingenuous to ignore the fact that multiple languages have separate shift arithmetic right operators.

The problem is that SAR cannot be introduced if SHR's backwards compatibility is to be maintained. The mnemonic would be broken, because SHR in Monkey1 currently performs the behavior which SAR is supposed to perform. Therefore, I am suggesting that SHR's behavior ignore the sign bit by default in MX2 so that SAR may exist and preserve the obvious mnemonic. I shouldn't need to argue the practical usefulness of an unsigned SHR -- but I will if you insist.


Danilo(Posted 2015) [#137]
Shift left seems to be the same anyway. It is in assembly language, and it is probably in computational mathematics.
I'm not a mathematician, and I think you are no mathematician. About RIGHT SHIFT, it seems you just want to have
two different ways: A right-shift that threats the input as an unsigned number, and a right-shift that threats the input
as a signed number. One right-shift that preserves the sign-bit, and one that just shifts right without preserving the
sign-bit.

Is that correct?

If that's correct, I fully agree. Actually, if I do a right-shift, I do it almost always thinking about unsigned numbers, thinking about bit-patterns
that shift, without any sign at all. That's the point where unsigned numbers support comes into play, at least for small types like
8-bit, 16-bit, and 32-bit Integers.
Some languages use '>>' and '>>>' to differentiate between unsigned and signed shift, and I think I could get used to that.
Same with different keywords like 'Shl' and 'Sar'. No problem, if documented.


Samah(Posted 2015) [#138]
So basically, Shl is <<, Shr is >> and Sar is >>>. Exactly how it is in BlitzMax. I really don't understand why Mark changed this for Monkey.