Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #268 User-defined operator

Define a type vector containing three floating point numbers x, y, and z. Write a user-defined operator x that calculates the cross product of two vectors a and b.

use std::ops::Mul;
struct Vector {
    x: f32,
    y: f32,
    z: f32,
}

impl Mul for Vector {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        Self {
            x: self.y * rhs.z - self.z * rhs.y,
            y: self.z * rhs.x - self.x * rhs.z,
            z: self.x * rhs.y - self.y * rhs.x,
        }
    }
}
record Vector(double X, double Y, double Z)
{
    public static Vector operator *(Vector a, Vector b)
    {
        return new(
            a.Y*b.Z - a.Z*b.Y,
            a.Z*b.X - a.X*b.Z,
            a.X*b.Y - a.Y*b.X
        );
    }
}
class Vector {
  final double x, y, z;

  Vector(this.x, this.y, this.z);

  Vector operator *(other) {
    return Vector(y * other.z - z * other.y, 
                  z * other.x - x * other.z,
                  x * other.y - y * other.x);
  }
}
module vect
  private
  type, public:: vector
     real :: x,y,z
  end type vector
  public:: operator(.x.)
  interface operator(.x.)
     procedure vector_cross
  end interface operator(.x.)
contains
  function vector_cross(a,b) result(c)
    type(vector), intent(in) :: a,b
    type(vector) :: c
    c%x = a%y*b%z - a%z*b%y
    c%y = a%z*b%x - a%x*b%z
    c%z = a%x*b%y - a%y*b%x
  end function vector_cross
end module vect
data Vector a = Vector a a a

infixl 7 ×
(×) :: Num a => Vector a -> Vector a -> Vector a
Vector x1 y1 z1 × Vector x2 y2 z2 = Vector (y1 * z2 - z1 * y2) (z1 * x2 - x1 * z2) (x1 * y2 - y1 * x2)
data Vector a = Vector a a a

infixl 7 `x`
x :: Num a => Vector a -> Vector a -> Vector a
Vector x1 y1 z1 `x` Vector x2 y2 z2 = Vector (y1 * z2 - z1 * y2) (z1 * x2 - x1 * z2) (x1 * y2 - y1 * x2)
use Object::Pad;
class Vector {
    has $x :accessor;
    has $y :accessor;
    has $z :accessor;

    BUILD { ($x, $y, $z) = @_ }

    use overload 'x' => sub { shift->xprod(shift) };

    method xprod ($v) {
        return Vector->new(
            $self->y * $v->z - $self->z * $v->y,
            $self->z * $v->x - $self->x * $v->z,
            $self->x * $v->y - $self->y * $v->x,
        );
    }
}

my $a = Vector->new(3, 4, 5);
my $b = Vector->new(5, 10, 1);
my $cross = $a x $b;
package Vector {
    sub new {
        my ($class, $x, $y, $z) = @_;
        bless [$x,$y,$z], $class;
    }
    sub x { shift->[0] };
    sub y { shift->[1] };
    sub z { shift->[2] };
    
    use overload 'x' => sub { shift->xprod(shift) };

    sub xprod {
        my ($self,$v) = @_;
        return Vector->new(
            $self->y * $v->z - $self->z * $v->y,
            $self->z * $v->x - $self->x * $v->z,
            $self->x * $v->y - $self->y * $v->x,
        );
    }
}
class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
        return

    def __mul__(self, other):
        return Vector(self.y * other.z - self.z * other.y,
                      self.z * other.x - self.x * other.z,
                      self.x * other.y - self.y * other.x)

result = a * b
Vector = Struct.new(:x, :y, :z) do
  def * (other)
    Vector.new(
      y*other.z - z*other.y,
      z*other.x - x*other.z,
      x*other.y - y*other.x)
  end
end
Structure Vector
    Public X, Y, Z As Double

    Shared Operator *(a As Vector, b As Vector) As Vector
        Return New Vector() With {
            .X = a.Y*b.Z - a.Z*b.Y,
            .Y = a.Z*b.X - a.X*b.Z,
            .Z = a.X*b.Y - a.Y*b.X
        }
    End Operator
End Structure

New implementation...
< >
tkoenig