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

Generics #527

Open
Moosems opened this issue Dec 10, 2024 · 12 comments
Open

Generics #527

Moosems opened this issue Dec 10, 2024 · 12 comments
Labels
big A lot of work to implement feature

Comments

@Moosems
Copy link

Moosems commented Dec 10, 2024

I couldn't find anything on generics, is that a language concept yet? Generally something that happens later though

@Akuli
Copy link
Owner

Akuli commented Dec 11, 2024

Generics are planned, but not implemented yet.

I hope that some day, I will add something like this to stdlib:

class List[T]:
    ptr: byte*
    length: long
    alloc: long

    @inline
    def append(self, elem: T) -> None:
        ...

    def extend(self, elems: T*, count: long) -> None:
        ...

    def end(self) -> T*:
        return &self->ptr[self->length]

    # ...other methods...

With this in stdlib, you could write:

import "stdlib/list.jou"
import "stdlib/io.jou"


def main() -> int:
    nums = List[int]{}
    nums.append(1)
    nums.append(2)
    nums.append(3)

    # Output: 1
    # Output: 2
    # Output: 3
    for p = nums.ptr; p < nums.end(); p++:
        printf("%d\n", nums.ptr[i])

    return 0

There is a reason why append() must be inline function. The element being appended has type T and it will be a stack variable. If the compiler generates a function named append() that is not inline, it will use a different amount of stack space depending on what type T is. This is considered bad style in C because it easily leads to stack overflow vulnerabilities. It's not supported at all in Jou, and I don't want to add it just for this.

If append() is not inlined, List.append() needs to take a pointer, so it will be annoying but not impossible to use. Inline functions don't exist yet in Jou, so the initial implementation of generics will probably have this annoyance.

@Moosems
Copy link
Author

Moosems commented Dec 11, 2024

Ok! I was actually asking because I noticed that you use Pointers a lot instead of a List type and after not finding generics supposed that was the reason why :D. How hard would inlining be to implement in jou?

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

For inlining, the compiler needs to:

  1. know which functions are inlined
  2. generate no code for definitions of inline functions
  3. basically copy/paste (that is, inline) contents of inline functions when they are called, with new dummy variables for everything that is local inside the inline function

"3." is the most difficult, of course, but everything seems doable.

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

Generics would also be useful for plain old functions.

There is currently no sort() function in standard library, although that would also require some kind of callback functions to define how to compare elements.

I recently added memswap() in #528 because it is not possible to write a generic def swap(a: T, b: T).

@Moosems
Copy link
Author

Moosems commented Dec 12, 2024

With generics should probably also come compile time type checking

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

Types are already checked at compile time. Jou's type checking is very similar to C: you can do dumb things with void* pointers (void* means "any pointer whatsoever"), but it's quite safe otherwise.

@Moosems
Copy link
Author

Moosems commented Dec 12, 2024

I meant it as in

foo = Variant[Bar | Baz](xyz)
if constrained(foo, Variant[Bar]):
    ...
elif constrained(foo, Variant[Baz]):
    ...

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

It seems like you are talking about tagged unions, like Rust's union, or Python's union types together with isinstance(). In my mind they don't really have anything to do with generics.

At some point I was going to add tagged unions, but now I feel like it's a Rust feature that doesn't really belong in Jou. I might change my mind eventually though.

@Moosems
Copy link
Author

Moosems commented Dec 12, 2024

I assume Jou doesn't do errors as a type then? :D

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

You're right. Jou is a simple language, not a full-featured language.

@Moosems
Copy link
Author

Moosems commented Dec 12, 2024

Actually, how do you handle exceptions/errors in Jou? I can't find anything about it in the docs (I'm on IRC and Discord if you want to talk about this elsewhere)

@Akuli
Copy link
Owner

Akuli commented Dec 12, 2024

Actually, how do you handle exceptions/errors in Jou? I can't find anything about it in the docs

I created #533.

(I'm on IRC and Discord if you want to talk about this elsewhere)

I will go to sleep soon. I might have more time tomorrow... :)

@Akuli Akuli added feature big A lot of work to implement labels Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
big A lot of work to implement feature
Projects
None yet
Development

No branches or pull requests

2 participants