-2

Is there a provision in any programming language such that we can write (a==b || a==c) as a==(b||c)?

In other words, is == distributive over logical OR in any programming language? (can we write (a==b || a==c) as a==(b||c)).

hnefatl
  • 5,860
  • 2
  • 27
  • 49
Issac Peter
  • 144
  • 10
  • Not in C, C++, or Java. b||c would mean both are boolean types. I don't think this makes sense. – duffymo Aug 07 '17 at 12:37
  • 2
    What would be the type of `b || c`? – Anton Gogolev Aug 07 '17 at 12:37
  • See python's [nice `in` syntax](https://stackoverflow.com/questions/12774279/how-to-check-if-a-variable-is-equal-to-one-string-or-another-string). It's totally different, but has a similar effect (and more succintly than the equivalent code in mainstream languages). – hnefatl Aug 07 '17 at 12:39
  • 1
    @AntonGogolev Would need to become a `Set` of choices instead of a boolean. And it would need to be overloaded to be able to append to the set in case of `b || c || d`. – Bergi Aug 07 '17 at 16:49
  • @AntonGogolev it's possible to create such type (see my answer). Maybe it's not common, but possible. That way I can't understand the downvotes. It's clearly a programming question. o-O – goteguru Aug 07 '17 at 21:25

1 Answers1

3

There are similar constructs in several languages. IN in SQL, in in python, etc, most evaluating lists or arrays. Closest one I know is Haskell's or which has the type [Bool] -> Bool.

As Anton Gogolev said, it's hard to find a good type for b || c, but not entirely impossible.

You may have to define the higher order function (|||) :: forall a . a -> a -> ((a -> Bool) -> Bool) implemented as a (|||) b = \f -> (f x) || (f y) (here \ means the lambda expression).

Now you can use this (b ||| c) (== 42).

Alternatively you could do :

(|||) ::  forall a b . a -> a -> (a -> b -> Bool) -> b -> Bool
(|||) x y f b = (f x b) || (f y b)

and now you can do ( a ||| b ) (==) 42

Of course none of the above will work in languages lacking higher order functions. Moreover, Equality (==) must be function and not language construct. (You can get similar effect with Promises, however).

Maybe the above lines give hints why this approach is not commonly used in the wild. :) a in [b,c] is much simpler to use.

EDIT: (for fun sake)

You can use wrapper type to achieve the goal (in Haskell):

data F a = (Eq a) => Fn (a -> (a->a->Bool) -> Bool) | N a
(===) :: Eq a => F a -> F a -> Bool
(Fn f) === (N n) = f n (==)  
(N n) === (Fn f) = f n (==)  
(N a) === (N b) = a == b
(Fn a) === (Fn b) = error "not implemented"

(|||) :: Eq a => F a -> F a -> F a
N a ||| N b = Fn $ \c f -> (a `f` c) || (b `f` c)
Fn a ||| N b = Fn $ \c f -> a c f || ( b `f` c )
N a ||| Fn b = Fn $ \c f -> b c f || ( a `f` c )
Fn a ||| Fn b = Fn $ \c f -> (a c f) || (b c f)

Now our new (===) is distributive over (|||). Some efforts has been made to keep associative and commutative properties. Now we can have all of the following:

 N 1 === N 2
 N 3 === ( N 3  |||  N 8  ||| N 5 )
 ( N 3  |||  N 8  ||| N 5 ) === N 0
 N "bob" === ( N "pete" ||| N "cecil" ||| N "max")
 N a === ( N 9 ||| N b ||| N c)

Everything will work smoothly. We could replace standard operators and type N with basic types and write 3 == (3 || 8 || 5). What you ask for is not impossible.

The construct is generic, you can easily extend it with something like (>=) :: F a -> F a -> Bool and now you can use ( 100 || 3 || a || b ) >= c. (Please notice that no lists or arrays are used.)

goteguru
  • 443
  • 3
  • 14