Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ad hoc function and type submodule declarations #1513

Open
lerno opened this issue Oct 3, 2024 · 11 comments
Open

Support ad hoc function and type submodule declarations #1513

lerno opened this issue Oct 3, 2024 · 11 comments
Labels
Discussion needed This feature needs discussion to iron out details Enhancement Request New feature or request
Milestone

Comments

@lerno
Copy link
Collaborator

lerno commented Oct 3, 2024

Possible syntax

module std::foo;
// Creates a sub module std::foo::bar in which hello() is placed.
fn void bar::hello() 
{
  ...
}
@lerno lerno added the Enhancement Request New feature or request label Oct 3, 2024
@Caleb-o
Copy link
Contributor

Caleb-o commented Oct 4, 2024

Assuming this only allows a single level of depth? So you can do bar::hello() but maybe not bar::baz::hello()?

@lerno
Copy link
Collaborator Author

lerno commented Oct 4, 2024

Exactly, it will be limited to single level for readability and also implementation should be more straightforward.

@lerno lerno added the Discussion needed This feature needs discussion to iron out details label Oct 4, 2024
@joshring
Copy link
Contributor

joshring commented Oct 8, 2024

If we look at the OOP world, do they ever create an implicit class in this sort of manner?

Personally I think a module is a fundamental organisational unit, I wouldn't want to create one implicitly, possibly by accident. I would always want to know I made an organisational unit and that I can use that further to do other interesting things with it.

I would want to be able to search for it, with module bar::new_module; to be able to find it.

Having things created without knowing we create a "mistrust" of modules as they are not concrete things I can easily look up. I feel like this would be a big missed opportunity to get people on-board with modules as something they can use and trust.

@Caleb-o
Copy link
Contributor

Caleb-o commented Oct 8, 2024

@joshring I feel like this is somewhat similar to declaring nested namespaces and classes. In something like C# and Java I believe, I could make a whole lot of nested classes and namespaces. I don't think this is too different from that, except this proposal only allows for a single level of depth.

Talking about OOP, I think something like Java allows you to just make anonymous classes and such, which might go against your searchability argument. So there's definitely worse options that other languages allow and this seems pretty reasonable from what I understand.

@joshring
Copy link
Contributor

joshring commented Oct 8, 2024

This is still fairly explicit though:

public class Container
{
    class Nested
    {
        Nested() { }
    }
}

and you can search for class Nested

Talking about OOP, I think something like Java allows you to just make anonymous classes and such, which might go against your searchability argument. So there's definitely worse options that other languages allow and this seems pretty reasonable from what I understand.

@joshring
Copy link
Contributor

joshring commented Oct 8, 2024

module std::foo;
// Creates a sub module std::foo::bar in which hello() is placed.
fn void bar::hello() 
{
  ...
}

When someone searches for bar they might find it here on this line, but they don't have any idea what it is, and there is no definition elsewhere you can look up.

In this example you always know it's a nested class (even me as a non-C# dev)

public class Container
{
    class Nested
    {
        Nested() { }
    }
}

@Caleb-o
Copy link
Contributor

Caleb-o commented Oct 8, 2024

I think there is one point that makes foo::bar() more obvious to what it is and that's the foo::. As far as I'm aware, the only thing that uses :: are modules. So you declare modules using this and also qualify things this way. Since this is used at the declaration, I feel like that might be more obvious than if it were to use some other pattern. So if I saw a function declaration with fn void foo::bar() {...} then I would probably assume it has something to do with modules, then eventually understand it was placed within the foo module.

There's one thing I'm not sure we've talked about though, how does this play with method syntax? (Maybe I've missed this)

A:

fn void foo::MyStruct.bar() { ... }

B:

fn void MyStruct.foo::bar() { ... }

Or is this solely for free functions?

@joshring
Copy link
Contributor

joshring commented Oct 8, 2024

So there is a hint that a module foo exists, but to my eyes there is no definition I would recognise for foo

Anonymous classes in Java, Polygon still exists outside as a definition I can look up

class Polygon {
   public void display() {
      System.out.println("Inside the Polygon class");
   }
}

class AnonymousDemo {
   public void createClass() {

      // creation of anonymous class extending class Polygon
      Polygon p1 = new Polygon() {
         public void display() {
            System.out.println("Inside an anonymous class.");
         }
      };
      p1.display();
   }
}

class Main {
   public static void main(String[] args) {
       AnonymousDemo an = new AnonymousDemo();
       an.createClass();
   }
}

@Caleb-o
Copy link
Contributor

Caleb-o commented Oct 8, 2024

You can also do this with interfaces in Java. I think that was where I was thinking about it. You can just create anonymous classes using an interface, which you might not pick up from search unless you go looking. There's also class expressions in languages like JS, which might not be spotted, also caused by the nature of JS.

So really, my main line of thinking is that a lot of languages have weird concepts you probably won't know or understand until you come across them and do a lookup in the docs. I'm still learning concepts about languages I've used now. That's also not really a bad thing. But anyway, I don't think foo::bar() is too crazy of a concept in the grand scheme of things and :: makes it more obvious of what it could be doing and you also have to qualify the function as foo::bar() to use it.

@lerno
Copy link
Collaborator Author

lerno commented Oct 8, 2024

Just as a clarification:

This thing is valid today:

fn void std::core::String.new_thing(self)
{}

And is nothing special, just an unambiguous way to write:

fn void String.new_thing(self)
{}

Note that for various reasons it doesn't matter if this new_thing method is defined in an imported module or not. It has immediate availability in all modules.

In my thinking it doesn't make sense for things like struct my_sub::AStruct { ... }, but it would be mainly for the occasional constructor function and to make converted constant enums from C APIs more friendly.

@joshring
Copy link
Contributor

joshring commented Oct 8, 2024

but it would be mainly for the occasional constructor function and to make converted constant enums from C APIs more friendly.

But anyway, I don't think foo::bar() is too crazy of a concept in the grand scheme of things and :: makes it more obvious of what it could be doing

I think open for extension is fine, but implicitly organising code seems like a mis-step because it can be over-used and become hard to maintain.

Not everything added is used in the way you expect is my concern.

I think one of the hallmarks of successful features in languages is easily being able to find the definitions of concepts in the code. That's why things like C/C++ macros are so hard, because they can nest and you don't know where the code is, leading to great complexity.

Perhaps not as bad as that, but could be easily misused, leading to spaghetti code from less experienced C3 programmers (which will be the majority for a while as C3 is new).

@lerno lerno added this to the 0.7 milestone Oct 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion needed This feature needs discussion to iron out details Enhancement Request New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants