Skip to content

Commit

Permalink
Start writing the modules chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Caleb-o committed Sep 21, 2024
1 parent e8a587a commit e683f93
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@

---

# The Basics
- [Hello World!](basics/hello_world.md)
[The Basics](basics/the_basics.md)
- [Hello World!](basics/hello_world.md)
- [Modules](basics/modules.md)
2 changes: 1 addition & 1 deletion src/basics/hello_world.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Functions in C3 use the `fn` keyword to denote a function declaration. It is the
Error: Functions from other modules must be prefixed with the module name.
```

Any function that comes from a different module, ***must*** be prefixed with its module name. This helps the reader also understand where this function comes from. We will see this often later, when it comes to types as well.
Any function that comes from a different module, ***must*** be prefixed with its module name. This helps the reader also understand where this function comes from. We will see this often later, when it comes to types as well. More with modules [here](modules.md).

> There is another way we can write this function. This will be familiar for those who have used JavaScript:
> ```c++
Expand Down
98 changes: 98 additions & 0 deletions src/basics/modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Modules

> 🚧 Work in progress 🚧
[Modules](https://c3-lang.org/references/docs/modules/) in C3 are quite interesting. Every file must start with a module declaration, as such `module mymodule`. A module is a container that namespaces our code. Later on, I will show how modules are our gateway into using generics.

Here's a list of things that will be covered:
- [Using modules and its properties](#using-modules)
- [Generics through modules](#generics-through-modules)

## Using Modules

As mentioned in our [Hello World](hello_world.md) example, we explained that a module is not tied to any file or directory. It was also mentioned that any file with the same module declaration, will be considered the same module and will share code. Let's take a look at what this means:

```c++
// foo.c3
module mymodule;
...

// bar.c3
module mymodule;
...
```

Here we can see that both our `foo` and `bar` files have `mymodule` declared. Some might see this as a potential error, since we're presumably on the same level using the same module. If you're coming from Go, this might be expected that these are the same. However, in C3, I can name these modules whatever I like, even when on the same level. So what if I change my code to this instead?

```c++
// foo.c3
module mymodule;
...

// hello/somewhere/bar.c3
module mymodule;
...
```

I have now moved `bar` into a new directory. Does this mean that I now have two `mymodule` modules? No. No matter where you declare the module, they will always be shared. So both of these are seen as the same module, which makes organisation so much easier. This is where I make the connection to languages with namespaces. If two files use the same namespace, wherever they be in my project files, I expect them to be part of said namespace. This now makes our imports so much easier, as we don't need to follow a path or traverse upwards or from the root. Here's how we would import this:

```c+++
import mymodule;
...
```

We can now use `mymodule` and it's as easy as that.

## Generics through modules

In C3, generics are expressed through modules. This is different to other languages, where you might write something like `<T, U>` on a type or function and be good. With C3, you do this at the module level instead.

```c++
module genericmodule(<Type>);

struct Foo {
Type bar;
}
```
Since we use the module, how does that look when importing?
```c++
import genericmodule;
```

This is just importing as normal? So how do we use the generic? We can use our `Foo` like this:

```c++
import genericmodule;

Foo(<int>) foo;

// or use define
def IntFoo = Foo(<int>);

IntFoo foo;
```
We can extend our generic module to include a function, that takes the generic value and returns it:
```c++
module genericmodule(<Type>);
struct Foo {
Type bar;
}
fn Type return_t(Type v) {
return v;
}
```

Using this function is quite similar:
```c++
import genericmodule;

fn void main() {
// NOTE: The generic parameter is required here, as well as the module name prefix
int a = genericmodule::return_t(<int>)(10);
}
6 changes: 6 additions & 0 deletions src/basics/the_basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The Basics

These examples are meant to get you started with C3, however, these will not be too in-depth around the whole language. For more detailed explanations of the language itself, you can visit [the official guide](https://c3-lang.org/guide/). This will cover only a few topics to help understand C3, but will not describe everything.

- [Hello World](hello_world.md): first program with details around its structure
- [Modules (WIP 🚧)](modules.md): small examples of how C3 uses modules

0 comments on commit e683f93

Please sign in to comment.