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

[Feature Request] Allow operator identifiers as fields in a struct. #557

Open
AZMCode opened this issue Jun 19, 2024 · 1 comment
Open

Comments

@AZMCode
Copy link

AZMCode commented Jun 19, 2024

This feature request is for allowing operator identifiers to be used as fields of a struct.

The motivating example for this is the simulation of typeclasses using implicit parameters.

For example, say a "numeric" typeclass is made:

pub struct num<a> {
    plus: (a,a) -> a
    minus: (a,a) -> a
    multiply: (a,a) -> a
}

An instance of this typeclass could then be used in a function as:

pub fun generic-pow<a>(x: a, y: a, .?num-instance: num<a>): a
    // Implementation here, using the functions provided in num-instance

However, as it stands this pattern breaks down when the function identifiers are operators, for example, this doesn't compile

pub struct num<a> {
    (+): (a,a) -> a
    (-): (a,a) -> a
    (*): (a,a) -> a
}

with the error

invalid syntax
unexpected identifier (operator) "(+)"
expecting ";", constructor field or "}"

And thus it is currently impossible for a typeclass to include operators, using this pattern.

I understand, however, that more considerations would have to be made about the associativity and priority of the operators, since the proposed snippet of code doesn't address that.

@daanx
Copy link
Member

daanx commented Sep 19, 2024

I think this is a bug since the grammar spec would allow this :-). I'll look into it.

btw. even if this is fixed, it may not be what you want since (+) as a field would still need to select from a struct, e.g. (num.(+))(1,2) -- and you cannot write 1 num.(+) 2 . What you want, is more like:

struct num<a>
  plus : (a,a) -> a

fun (+)( x : a, y : a, ?num : num<a> ) : a
  (num.plus)(x,y)

val int/num : num<int> = Num( int/(+) )
val bool/num : num<bool> = Num( (^) )

fun test() 
   (1 + 2, true + false).println        // pretending we did not import (+) : (int,int)->int

We are still experimenting with language design here; maybe we need a class definition that expands like above; see also test/overload/monad3.kk etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants