rafaqz / Interfaces.jl

Macros to define and implement interfaces, to ensure they are checked and correct.
MIT License
72 stars 4 forks source link

Anonymous functions in interface definition #13

Closed gdalle closed 8 months ago

gdalle commented 1 year ago

Thanks for this cool package! Could you explain the rationale behind the -> syntax in the @interface macro?

@interface AnimalInterface (
    mandatory = (;
        age = (
            x -> age(x) isa Real,
            x -> age(x) >= 0,
        )
    ),
    optional = (;
        walk = x -> walk(x) isa String,
        talk = x -> talk(x) isa Symbol,
        dig = x -> dig(x) isa String,
    ),
)

Would something like this also work, and perhaps be simpler to write?

@interface AnimalInterface (
    mandatory = (;
        age = (
            age(x) isa Real,
            age(x) >= 0,
        )
    ),
    optional = (;
        walk(x) isa String,
        talk(x) isa Symbol,
        dig(x) isa String,
    ),
)

If we don't need to specify the number of arguments of the methods, we could even do something like

@interface AnimalInterface (
    mandatory = (
        age -> (
            Real,
            >= 0,
        )
    ),
    optional = (
        walk -> String,
        talk -> Symbol,
        dig -> String,
    ),
)

Of course the syntax is invalid, I'm more interested in the general idea :)

rafaqz commented 1 year ago

Yeah that's nice, but maybe not explicit enough? Don't you think assuming the function name is the same as the trait name is maybe a little too coupled and inflexible?

Generally the way it is now is just the simplest possible macro to implement that does whats required, it's pretty much just julia code that gets picked up and put in the right places. But its also pretty clear what you have to do, so I'm not totally sure about what improving it would look like. Your examples are both less flexible and less obvious by not being regular syntax (although they are clearly nicer to read). But it might be worth having a real DSL for this, feel free to have a go.

I wrote this package in some gaps when I was working 6 days a week, not much time for fiddling with macros like that.

gdalle commented 1 year ago

Don't you think assuming the function name is the same as the trait name is maybe a little too coupled and inflexible?

Ooooh I hadn't understood that it was possible, that makes a ton of sense! And in that case your syntax is clearly preferable.

I wrote this package in some gaps when I was working 6 days a week, not much time for fiddling with macros like that.

I'm very grateful, I was just opening a discussion about esthetics but in light of what's above it isn't wise after all :)

rafaqz commented 1 year ago

I think there are definately some improvements to be made, but we would need to do them in the process of writing a base or package interface to make sure it makes sense.

Its similar to the underscore piping anonymous function conversation, it usually ends back at "just write out the anyonymous function"

gdalle commented 9 months ago

Does the function have to be anonymous?

rafaqz commented 9 months ago

No, anything callable should work