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

Question: Overloading existing operators #25

Open
nighthawk opened this issue Oct 3, 2019 · 2 comments
Open

Question: Overloading existing operators #25

nighthawk opened this issue Oct 3, 2019 · 2 comments

Comments

@nighthawk
Copy link
Contributor

I'm experimenting with using AnyExpression and its powerful support for custom data types and operators. This is working well, though I'm facing an issue when I want to use the same operator as defined by Expression (or AnyExpression) itself, but only use my overload for the custom data types and falling back to the default implementations otherwise.

Say, for example in have a "date" datatype which is really just Swift's Date, and I want to allow comparisons using <, <= and their friends, but if I define those as .infix("<") then this now works for my date types, but regular numeric expressions now fail.

I've tried following this from the README:

If you are using the init(impureSymbols:pureSymbols:) initializer, you can fall back to the standard library functions and operators by returning nil for unrecognized symbols.

However, I can't return nil at that stage, as I'd have to return nil from within the operator's SymbolEvaluator as it depends on the specific arguments.

Is this possible or do I have to reimplement the default behaviour in my custom operator?

@nicklockwood
Copy link
Owner

There's not a super-elegant way to do this right now, but basically yes you'd need to reimplement the standard operator logic inside your own handlers. Here's an example:

let expression = AnyExpression(parsed) { symbol in
    switch symbol {
    case .infix("<"):
        return { args in
            switch (args[0], args[1]) {
            case let (lhs as Date, rhs as Date):
                return lhs < rhs
            case let (lhs as Double, rhs as Double):
                return lhs < rhs
            default:
                throw Expression.Error.message("Type mismatch")
            }
        }
    default:
        return nil
    }
}

@nighthawk
Copy link
Contributor Author

Thank you for the quick response! I’ll go with that for now, but would be nice to have a more elegant way down the track where the duplication wouldn’t be necessary.

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

No branches or pull requests

2 participants