Module statement, With statement

Community Forums/Monkey2 Talk/Module statement, With statement

Nobuyuki(Posted 2015) [#1]
Okay, I'm aware that Monkey has a sorta module scope where it checks for built-in modules if it can't find the proper import relative to the entry point file. However, Module is still a reserved keyword, and I was wondering what everyone thought of using it to create some namespace magic to make calling modules easier, ala .NET. Por ejemplo:

File 1, ./simpleui/Pushbutton.monkey
Module SimpleUI  'When linking, all modules with dupe identifiers can get tossed into this namespace?  Could be good, could be bad, would definitely require warnings if dupes existed in different places,  but better when a module has multiple files..
  Class PushButton
  Field x,y,w,h
    Method Poll:Void(xOffset#, yOffset#)
      'code
    End
  End

End Module


File 2, ./main.monkey
Import Mojo
Import simpleui.pushbutton

Function Main:Int()
  Local a:=New SimpleUI.PushButton()
End



In addition, a With statement can be used as syntactic sugar to reduce typing fully-qualified class, function, or instance names within a code block.

File 3, ./main.monkey, alternate version
Import Mojo
Import simpleui.pushbutton

Function Main:Int()
  With SimpleUI  'Matches named module.  Look for declarations within this module's scope if none can be found in current context.  
    Local a:=New PushButton()
    With a  'Matches instance. Member syntax is now abbreviated, reference operator still required. 
      .x = 8;  .y = 8;  .w = 128;  .h = 32
    End With
  End With
End Function



I'm guessing if class-in-class is supported, then none of the Module stuff is really necessary. Main purpose here is to reduce naming conflicts with other people's code, and possibly have Friend as a scope level. Projects with code unique to the project can live within its own module scope and import other code from other modules with the same name without requiring an alias to resolve naming conflicts (a good example would be importing os and mojo at the same time). The main purpose of With is syntactic sugar to reduce typing when subclasses run several levels deep. Perhaps With blocks can be declared outside of method scope, similar to how .net's Imports works?


Samah(Posted 2015) [#2]
I like it. It'd certainly make namespaces easier to manage, and it would make the Friend visibility modifier a bit "friendlier" too.
The With keyword takes me back to my VB6 days, so my feelings are somewhat conflicted. XD


marksibly(Posted 2015) [#3]
I agree with the general idea, but I think we should use 'namespace' instead of 'module'.

This is because I think it's important to separate out the 2 ideas of a 'module on disc', and a 'namespace you use in code'. So a module is a physical .monkey file (that gets converted to .cpp and .o files etc) while a namespace is a logical scope that can be referred to in code. So, you 'Import' modules, but 'Use' (or 'With' or whatever) namespaces.

IMO, how/where source is stored should be mostly irrelevant, to the point were I'd (almost) argue that Import of monkey modules should be #Import "path_to_monkey_file". It's a filesystem thing, and code shouldn't have to deal with that. But don't panic, I wont be doing that!

By default, if a module does not specify a namespace, its namespace can be the same as its module name.

I definitely don't like the current situation in monkey1 where you can't split up a big module into smaller modules without affecting everything's namespace!


Samah(Posted 2015) [#4]
@marksibly: So a module is a physical .monkey file (that gets converted to .cpp and .o files etc) while a namespace is a logical scope that can be referred to in code. So, you 'Import' modules, but 'Use' (or 'With' or whatever) namespaces.

Sounds good. I like the Using keyword for namespaces, too.

@marksibly: Import of monkey modules should be #Import "path_to_monkey_file"...But don't panic, I wont be doing that!

Actually I agree with this.

@marksibly: By default, if a module does not specify a namespace, its namespace can be the same as its module name.

To be honest I'd prefer it to be a compilation error. If we're going to bring in namespaces, the developer should learn what they are and how to use them. Not having a "magic default" would make things easier to manage visually, too.


Danilo(Posted 2015) [#5]
Nobuyuki wrote:
Import Mojo
Import simpleui.pushbutton

Function Main:Int()
  With SimpleUI  'Matches named module.  Look for declarations within this module's scope if none can be found in current context.  
    Local a:=New PushButton()
    With a  'Matches instance. Member syntax is now abbreviated, reference operator still required. 
      .x = 8;  .y = 8;  .w = 128;  .h = 32
    End With
  End With
End Function


In my opinion it's not neccessary to differentiate between different 'With' possibilities.
'With' could just be a substitution for identifiers that start with a dot, like:
Import Mojo
Import simpleui.pushbutton

Function Main:Int()
    With SimpleUI                                   ' Top substitution gets 'SimpleUI'

        Local a:=New .PushButton()                  ' .PushButton() becomes SimpleUI.PushButton()

        With a                                      ' Top substitution gets 'a'
            .x = 8;  .y = 8;  .w = 128;  .h = 32
        End                                         ' End/EndWith pops the top With, so
                                                    ' we are back at 'SimpleUI' now
                                                    ' Nested 'With' is implemented as a simple stack
                                                    ' of substitution names, nothing fancy

        Local b:=New .PushButton()                  ' .PushButton() becomes SimpleUI.PushButton()

    End

    '
    ' With should not just work with simple identifiers
    '
    With myWindow
        .Title = "MonkeyX2 Window"                  ' myWindow.Title

        With myWindow.Position
            .x = 100                                ' myWindow.Position.x
            .y =  50                                ' myWindow.Position.y
        End

        With myWindow.Size
            .width  = 800                           ' myWindow.Size.width
            .height = 600                           ' myWindow.Size.height
        End
    End

    For i:=0 to 100

        With Something[i].blah.ho
            .blub = 12                              ' Something[i].blah.ho.blub
            .gurp = 18                              ' Something[i].blah.ho.gurp
        End

    Next

End

With this it's basically just a text substitution. If we always have to use the dot in front of identifiers
that use the current 'With substitution', it is very clear what the full name is. And no naming conflicts with that.

The "Using Namespace" is a separate thing. It doesn't require the dot in front of identifiers,
as it imports names from a namespace into the global/current namespace.


GW_(Posted 2015) [#6]
IMHO, 'With' is nice and all, but seems like a post v1.0 kind of feature. Dangling 'end' statements would be a real turnoff though. 'endwith' is more Blitz* style.


Danilo(Posted 2015) [#7]
I just used 'End' because MonkeyX usually allows 'End' + 'End With' + 'EndWith'. It's very flexible, and I like that. :)


Samah(Posted 2015) [#8]
@GW_: Dangling 'end' statements would be a real turnoff though. 'endwith' is more Blitz* style.

To be honest I hate the fact that you CAN'T do this in BlitzMax. Coming from a code-blocks-by-braces background, it annoys me that I need to match the block type every time in Max.


itto(Posted 2015) [#9]
Please leave the closing "end" valid for every block, and also the possibility to write keywords all in lowercase! :(
Monkey is one of the few language with a BASIC-like syntax which manages not to get too verbose... I hope Monkey 2 will go in the direction of try to be even less verbose and with a cleaner syntax, and not the contrary!


Nobuyuki(Posted 2015) [#10]
@Samah

The With keyword takes me back to my VB6 days, so my feelings are somewhat conflicted. XD
...
Sounds good. I like the Using keyword for namespaces, too.



The main reason I suggested With..End With over Using is because in .Net, Using..End Using is used for automatic resource disposal of iDisposable objects, its own syntacticaly-sweet pattern of dealing with semi-managed objects like file streams and the like. I believe With is only known outside of the VB world as a concept in Python, and the usage scenario may be a bit different, but in any case it seemed interesting to "expand" With's application to include part of the functionality which .Net's Imports statement does with namespaces already (and which Monkey currently doesn't, since Import deals strictly with modules as of Monkey1). This seems to kill two birds with one stone -- keeping Import's functionality unobfuscated from an initial glance, and providing functionality that neatly groups both namespace importing, and "temporary scope shifting" into one keyword block.

I generally agree with the notion that modules and namespaces should remain as unobfuscated and clear in the import precedence as possible.

@Danilo

In my opinion it's not neccessary to differentiate between different 'With' possibilities.
'With' could just be a substitution for identifiers that start with a dot
...
The "Using Namespace" is a separate thing. It doesn't require the dot in front of identifiers,
as it imports names from a namespace into the global/current namespace.



That would certainly be more syntactically consistent, although it may make it more difficult for the person reading the code to tell the difference between a member of a namespace and the member of a class without an IDE to help them. It sounds like using "Using" and With both would be the way to tell the difference, but then you have a bit of a situation where you're using two different keywords depending on context. Hmmm, all seems to depend on when and where are good places to differentiate class scope and namespace scope.

@itto
I hope Monkey 2 will go in the direction of try to be even less verbose and with a cleaner syntax, and not the contrary!

all a matter of opinion.... Coming from a VB background, I prefer the verbosity and feel it increases readability of code blocks. } soup is very difficult for me personally to read. Glad Monkey allows the variation or else I'd likely be inserting the verbosity in comments...


Samah(Posted 2015) [#11]
@Nobuyuki: The main reason I suggested With..End With over Using is because in .Net, Using..End Using is used for automatic resource disposal of iDisposable objects...

I'm talking about the "using" statements that appear at the top of a file, like Monkey/Java's "import".
GG at reusing a keyword, Microsoft.


Nobuyuki(Posted 2015) [#12]
@samah

I get you, and I wouldn't be opposed to that usage if that's what most people prefer. It does weaken the case for powerful (and perhaps unique) With blocks though :)