AdeptLanguage / Adept

The Adept Programming Language
GNU General Public License v3.0
124 stars 9 forks source link

[improve] Improve support for function aliases #32

Closed IsaacShelton closed 4 years ago

IsaacShelton commented 4 years ago

[improve] Allow for variadic and varargs (without indirectly forcing it)

func alias echo(..) => print
func alias strictPrintf(*ubyte, ...) => printf

[bug] Also this should compile, but doesn't:

import basics

func print(a int){
    a = 10
}

func alias echo() => newline
func alias echo(String) => print
func alias echo(int) => print

func main {
    echo("Hello World")
    echo()
    echo("This is a test")
    echo(12345)
}

func echo(value int){
    print(toString(value).reversed())
}

It should prefer the function named echo over the function alias, but it fails to compile.

IsaacShelton commented 4 years ago

Bug fixed in 70919eb8b0512a777a9788e7a8da090b02b54296, however the behavior of what happens when a function alias and a real function overlap now is now different. Until a better collision resolution method is decided upon and implemented, which function is called is determined by whether the function that the function alias is pointing to is declared before the real function. If the pointed to function is declared first, then it is called, otherwise the real function is called.

Full support for old-style and Adept-style variadic arguments in function aliases is yet to be implemented

ghost commented 4 years ago

@IsaacShelton It works like this:

// new syntax

sum :: func(x, y : int) : int {
        return x + y
}

func alias add(int, int) => sum

I think after you improve it to automatically detect types, I think you can add new syntax for aliases too (if you want):

// new syntax

sum :: func(x, y : int) : int {
        return x + y
}

alias add :: func(int, int) => sum // or something like this
IsaacShelton commented 4 years ago

@t0md3an

Yes I agree there should be support for :: with function aliases, probably something like:

add :: func alias (int, int) => sum

And also, yes, having something that automatically does the types:

// Targets the first declared 'sum' function
add :: func alias => sum
IsaacShelton commented 4 years ago

These have been added in c00b44efc734aa52c1c1a04ac8bc5cc3059cf2e7 and a47b7615c3380d61dae9492eb6bca9264768f5de.

ghost commented 4 years ago

@IsaacShelton I think everything works correctly and this issue should be closed. Is there anything to improve here?

IsaacShelton commented 4 years ago

@t0md3an I just finished adding the last thing in 48b406dd239d1e716acf9143c5420829f75f547c. This issue is good to be close now.

ghost commented 4 years ago

@IsaacShelton What do you think about changing new-style syntax from this:

add :: func alias => sum

to this:

alias add :: func => sum

I think this is more readable and logically:

alias var = variable
alias add :: func = sum
IsaacShelton commented 4 years ago

@t0md3an Sorry, I disagree, I plan on adding syntax for struct/union/global variable aliases, and I think this would fit more with the name preceding the content. The idea behind :: is to have the name before the definition, and having alias before the name gets rid of that. The non-:: style is where alias would be better preceding the definition I feel.

I am still considering how to make the two alias syntaxes more similar though. I don't like how the current alias syntaxes are very different from each other.

One possibility would be to get rid of the alias keyword

// The problem with this, is it's easy confuse whether or not you're dealing with an alias

sum :: func => add
IntPair :: struct => <int> Pair

func sum => add
struct IntPair => <int> Pair

Another would be to do this:

// The problem with this, is I want to avoid making 'type' a keyword
// Overall, this looks pretty clean though

sum :: func alias => add
IntPair :: type alias => <int> Pair

Or violate the :: name rule:

// I don't like these really

alias sum func => add
alias IntPair => <int> Pair

alias sum => func add
alias IntPair => <int> Pair

// This one isn't too bad actually

alias sum = func add
alias IntPair = <int> Pair

Maybe collapsing them into something like this would work though:

sum :: alias = func add
sum :: alias = func add(int, int)
IntPair :: alias = <int> Pair

alias sum = func add
alias sum = func add(int, int)
alias IntPair = <int> Pair

I've been thinking about a better syntax for this, but I still I think I like this the best so far:

// CURRENT

func alias sum => add
alias IntPair = <int> Pair

sum :: func alias => add
IntPair :: alias = <int> Pair

I'll explore more syntax possibilities, but I haven't found anything I like better yet. There's no real "good" syntax for this I feel

ghost commented 4 years ago

@IsaacShelton I think you are right