views:

4662

answers:

53

I'm doing this to learn the syntax of different programming languages.

So, how would you defined the following class along with with its operations in your favorite programming language?

alt text

Image generated by http://yuml.me/

And a main method or equivalent to invoke it:

For instance, for Java it would be:

...
public static void main( String [] args ) {
    Fraction f = new Fraction();

    f.numerator( 2 );
    f.denominator( 5 );
    f.print();
    // using the "getters"
    int n = f.numerator();
    int d = f.denominator();
}
....

EDIT

This is not intended for production code!

The purpose is merely to learn from others how to write the most basic data structure.

I know and agree that immutability is much better and the class needs a "test-specification" to work properly and Fraction is already a core class in many languages. Forget about the semantics

+14  A: 

Ruby:

class Fraction
  attr_accessor :numerator, :denominator

  def print
    "#{numerator}/#{denominator}"
  end
end

f = Fraction.new
f.numerator = 2
f.denominator = 3
f.print # => "2/3"
n = f.numerator
d = f.denominator
Pete
Good answer in ruby!
fastcodejava
+3  A: 

I disagree with a mutable class for this. The following example still allows the numerator/denominator "setters" but returns a new Fraction object. The names are withNumerator and withDenominator to indicate this fact but they could easily be numerator or denominator (or even numerator=/denominator=, but that's just ... wrong):

case class Fraction(_numerator: Int, _denominator: Int) {
  def numerator = _numerator                            // getter
  def withNumerator(n: Int) = Fraction(n, _denominator) // returns NEW object
  def denominator = _denominator
  def withDenominator(n:Int) = Fraction(_numerator, n)
  override def toString = "" + numerator + "/" + denominator
  def print = println(this)
}

val f = Fraction(0,0).withNumerator(22).withDenominator(7)
f.print                // 22/7
val n = f.numerator
val d = f.denominator

Here is a version that just exposes the members directly so they are mutable:

case class Fraction(var numerator: Int, var denominator: Int) {
  override def toString = "" + numerator + "/" + denominator
  def print = println(this)
}

val f = Fraction(0,0)
f.numerator = 22  // direct member access
f.denominator = 7
f.print           // 22/7
val n = f.numerator
val d = f.denominator

Here is a version with plain "getters/setters" (just wrap the members and mutate the object):

case class Fraction(var _numerator: Int, var _denominator: Int) {
  def numerator = _numerator               // getter
  def numerator_=(n: Int) = _numerator = n // setter -- mutating
  def denominator = _denominator
  def denominator_=(n:Int) = _denominator = n
  override def toString = "" + numerator + "/" + denominator
  def print = println(this)
}

val f = Fraction(0,0)
f.numerator = 22   // setter -- mutating
f.denominator = 7
f.print            // 22/7
val n = f.numerator
val d = f.denominator
pst
If you don't like making mutable classes (which is entirely understandable), why not make an immutable version (where setters return a new copy of the class)?
Gabe
I think `val g = f.denominator(17)` is more in the spirit of the exercise.
Gabe
@Gabe - For you :)
pst
A: 

C#

public class Fraction
{
    public Fraction() {}

    public int numerator { get;set; }
    public int denominator { get;set; }
    public override ToString( ) 
    {
        return this.numerator.ToString() + "/" + 
               this.denominator.ToString(); 
    }
    public void Print() 
    {
         System.Console.WriteLine( this );
    }
    public static void Main( string [] args ) 
    {
        Fraction f = new Fraction();
        f.numerator = 2;
        f.denominator = 5;
        f.Print();
     }
}
Muad'Dib
`System.Console.Println`???
Dan Tao
I wouldn't recommend putting `Main` inside some arbitrary class.
Gabe
+9  A: 

C++

#include <iostream>

class Fraction
{
    int m_numerator;
    int m_denominator;
public:
    Fraction(int numerator, int denominator) 
        : m_numerator(numerator)
        , m_denominator(denominator) {
    }
    void SetNumerator(int val) {
        m_numerator = val;
    }
    void SetDenominator(int val) {
        m_denominator = val;
    }
    int GetNumerator() const {
        return m_numerator;
    }
    int GetDenominator() const {
        return m_denominator;
    }
    void print() const {
        std::cout << m_numerator << "/" << m_denominator;
    }
};

// Main method - Entry point
int main()
{
    // declare an instance of the class
    Fraction f(5,5);
    f.print();
}
George Edison
Dude, I am trying to edit this as fast as I can... give me a chance!
George Edison
Kotti
@Kotti: Fixed. Like I said... I am throwing this together in a batch of edits. Eventually it will be perfect :)
George Edison
:) This also means you should add getters for numerator and denominator (as the UML up there says)...
Kotti
K. I didn't see that posted up there 'till now.
George Edison
`using namespace std` in a class definition file?
Tom Hawtin - tackline
This is an example... not production code. Obviously I would not put this here if it were not just a demonstration. **But** since it is, I put it there for completeness.
George Edison
@Tom: it's not a class definition file, at least probably not since it contains the definition of `main`. More to the point, `using namespace std` in order to avoid typing `std::` one single time?
Steve Jessop
Alright, alright. I'll fix it.
George Edison
You should make the getters and print() const;
GogaRieger
Good point. I fixed that.
George Edison
-1 for creating an uninitialized object. Add a constructor and remove the settters!
TimW
@TimW: You know, the point of Community Wiki posts is that you can do that yourself. I've done it now. And the original question requires that the setters be there.
Billy ONeal
I think the "most C++" way to do this would be to make this `template <typename T> class Fraction { ... }` and then you can `typedef Fraction<int> IntFraction` but that's not exactly following the spec.
Chris Lutz
Wow. C++ sucks. :) ... but I still use it.
Łukasz Lew
+16  A: 

C ;-)

#include <stdio.h>

struct Fraction {
    int numerator;
    int denominator;
};

void Fraction_print(const struct Fraction *f) {
    printf("%d/%d\n", f->numerator, f->denominator);
}

int main() {
    struct Fraction f = {1, 2};
    Fraction_print(&f);
    f.numerator = 2;
    f.denominator = 3;
    Fraction_print(&f);
    return 0;
}

Obviously if you want to do stuff like reduce to simplest form in the setters, you can define those as functions too.

Steve Jessop
Looks **a lot** like the Go version ( I mean, the other way around, Go look like C )
OscarRyz
In particular the fact that Go defines methods "outside" the class.
Steve Jessop
I've added a Go version for comparison, although I'm not convinced it's very good.
Steve Jessop
in Fraction_print you want to use `->` instead of the dot operator to access the pointer struct members, since `f` is a pointer.
Luca Matteis
C is not object-oriented, which does not mean you cannot code in object-oriented style, however, I do not see any classs, which could be used to create objects with coupled state and behaviour.
Gabriel Ščerbák
@Gabriel: many of the languages listed here have eccentricities which make the spec impossible to implement precisely - "print" being a keyword, lack of overloading. In this case, lack of direct language support for classes. As any low-level programmer "knows", objects with behaviour are syntactic sugar for there being some way to call the right function. In this case, the right function is known at compile-time and specified by the programmer. Likewise there's no need to whip up a virtual call mechanism for this case, since there is no requirement for polymorphism, although it could be done.
Steve Jessop
@Steve Jessop I am aware of that, therefore i wrote: "which does not mean you cannot code in object-oriented style" by which I ment that more semantic effort could be made to get it right. For a struct to behave like a class, you need a mechanism for copying the struct (at least, let us say, we do not need constructor in this case). Also the function is part of Fractions behavior, so I would expect it to be assigned function pointer in the struct.Do not get me wrong, I like C (I started programming with C++...), but I hate when people talk about classes and OOP, but think procedures.
Gabriel Ščerbák
"would expect it to be assigned function pointer in the struct". Well, that's precisely the question of whether a virtual call mechanism (or, some say, inheritance) is required before you're "allowed" to call something OO, or call something a class. Are C++ classes with no virtual member functions "really classes"? To a Java programmer, probably they're not, but that doesn't mean C++ programmers should go around adding virtual members *to classes which don't need them*, just to make Java programmers happy ;-) Not sure what you mean about copying: C assignment works for my Fraction.
Steve Jessop
You should typedef the struct into an abstract data type, that gives you more of a 'class' type to work with. In real C you would also hide the struct internals in a .c file so the programmer using your type can't access the members.
Mike Weller
Done: http://stackoverflow.com/questions/2702450/implement-a-simple-class-in-your-favorite-language/2771898#2771898
Mike Weller
I've heard of `C++`. I've I've heard of `C#`. I've heard of `C*`. I've even heard of `C--`...but I've never heard of `C;-)`.
Mike Graham
A: 

Another attempt on C++

class Fraction {
   int m_numerator, m_denominator;

public:
   int numerator() const {
      return m_numerator;
   }
   int denominator() const {
      return m_numerator;
   }
   void numerator(const int new_numerator) {
      m_numerator = new_numerator;
   }
   void denominator(const int new_denominator) {
      m_denominator = new_denominator;
   }
   void print() const {
      // Printing implementation
   }
};

void main() {
   Fraction f;
   f.numerator(2);
   f.denominator(5);
   f.print();
}
Kotti
Declaring arguments as const as in `const int new_numerator` does nothing, as integral arguments are passed by value anyway.
el.pescado
Ferruccio
-1 for creating an uninitialized object. Add a constructor and remove the settters!
TimW
No constructor + setters in the UML means no constructor and setters in my code.
Kotti
+7  A: 

Python 2:

class Fraction(object):
    def __init__(self, numerator=0, denominator=1):
        self.numerator = numerator 
        self.denominator = denominator
    def __str__(self):
        return "%s / %s" % (self.numerator, self.denominator)

def main():
    f = Fraction(1, 2)
    print f
    f.numerator = 2
    f.denominator = 3
    print f

if __name__ == "__main__":
    main()
Steve Jessop
You should add a `__str__` method, or even a `__repr__` one :) And you beat me by 51 seconds... netbook isn't that good to type after all :D
Ivo Wetzel
Yeah, I should add docstrings too, but I think we're going for implementing the spec (approximately: I truly cannot be bothered defining trivial getters and setters), rather than showing quite all the usual boilerplate ;-) Maybe I should have left out `if __name__ == "__main__"`, but it is "how you write a main function" in Python.
Steve Jessop
you can't call a method "print" in python 2.
nosklo
I sort of disagree with inheriting from `object` in an illustrative example. New-style classes are an optional bolt-on, nothing wrong with using them for everything but also not required.
Steve Jessop
@Steve, It's your post, so you can of course make the judgment call and edit it back. *Personally*, I prefer not to post example code on the internet for people to look at that relies on long, **long** deprecated language features that limit the usefulness and aesthetics of the created thing.
Mike Graham
Aesthetics? You think `(object)` is beautiful? ;-). I won't edit it back, it's best practice, but I very much hope that someone can be bothered to add docstrings on the same grounds. I'll believe that old classes are deprecated in Python 2 when the documentation no longer says, "this manual ... may still be lacking in some areas when it comes to its coverage of new-style classes". At current rate of progress, that will be when Python 2 is no longer supported...
Steve Jessop
@Steve, The aesthetic advantage comes from the fact new-style classes are much more like built-in types than old-style classes. For example, `type(f)` gives a meaningful result.
Mike Graham
+3  A: 

ABAP:

CLASS Fraction DEFINITION.
  PUBLIC SECTION.
    METHODS numerator IMPORTING i_numerator TYPE I.
    METHODS denominator IMPORTING i_denominator TYPE I.
    METHODS ToString RETURNING value(r_fraction) TYPE string.
    METHODS Print.
  PROTECTED SECTION.
    DATA: v_numerator TYPE   I,
          v_denominator TYPE I.
ENDCLASS. ""End Definition

CLASS Fraction IMPLEMENTATION.
  METHOD numerator.
    v_numerator = i_numerator.
  ENDMETHOD.

  METHOD denominator.
    v_denominator = i_denominator.
  ENDMETHOD.

  METHOD ToString.
    CONCATENATE v_numerator
                "/"
                v_denominator
           INTO r_fraction.
  ENDMETHOD.

  METHOD Print.
    DATA v_fraction.
    CONCATENATE v_numerator
                "/"
                v_denominator
           INTO v_fraction.
    WRITE: v_fraction, /.
  ENDMETHOD.

ENDCLASS. "End Implementation
BenV
Oh god... is this language real?
Mark
ABAP - the language of SAP. I code in it every day at work! Aren't you jealous :)
BenV
I did work experience at a large software company for a few weeks and coded in ABAP after knowing C#, Java, Python and (Some) Haskell. I nearly died.
Callum Rogers
One of the scariest moments of my life came when I was doing some C# coding at home one day and wrote an if statement in ABAP syntax without thinking.
BenV
+1  A: 
SeanJA
Alas... print is a reserved word so it cannot be used as a function name (apparently).
SeanJA
+12  A: 

F#: lots of different ways to make classes:

Vanilla class:

type Fraction(numerator : int, denominator : int) =
    member this.Numerator = numerator
    member this.Denominator = denominator
    override this.ToString() = sprintf "%i / %i" numerator denominator

let f = new Fraction(2, 3)

Record:

type fraction = { numerator : int; denominator : int }
    with
        override this.ToString() = sprintf "%i / %i" this.numerator this.denominator

let f = { numerator = 2; denominator = 3 }

Union:

type fraction = Fraction of int * int
    with
        member this.Numerator = match this with Fraction(x, y) -> x
        member this.Denominator = match this with Fraction(x, y) -> y
        override this.ToString() = match this with Fraction(x, y) -> sprintf "%i / %i" x y

let f = Fraction(2, 3)

Usage:

printfn "%O" f
Juliet
+19  A: 

Python:

from fractions import Fraction
Mike Graham
-1 - This is just... this is just terrible! (Humorous but terrible!)
George Edison
@George, this is the correct implementation in Python.
Mike Graham
It's correct Mike, but, that was just a name, mentally you could replace `Fraction` with `Fraccionamiento`, `numerator` with `nabucodonosor` and `denominator` with `dumerangulas` ( unless python is very extensive, there shouldn't be a module with that definition !!)
OscarRyz
True , but the OP asked for the class defintion. This ain't it.
George Edison
@Oscar: There is a Python module with almost *every* name.
George Edison
Guys! GUYS!!! This is a tongue-in-cheek answer meant to make you smirk and if, to serve as a serious response, to indicate, "In Python we rely on the same standard, high-quality implementations of what we need rather than cobbling together a half-featured, buggy implementation ourselves."
Mike Graham
@Mike: how about in Python 2.5, then? ;-)
Steve Jessop
@Steve, a) You are so hopelessly literal and rigid, b) `from sympy import Rational`, c) thhhhhhhhpbt.
Mike Graham
+1 I liked the joke and I think it's sad that Mike had to explain it.
ssg
ITYM `from sympy import Rational as Fraction`. I am hopelessly literal and rigid - I maintain that in all languages, not just Python, you wouldn't touch the class specced in the question with a barge pole.
Steve Jessop
@Steve, Well at least you admit it. `=p`
Mike Graham
If you look at Dustin's answer below (currently on the second page) you can see why Python people prefer this one.
Donal Fellows
@Donal, FWIW, people probably don't especially like that solution since it uses several Python antipatterns to answer the question very directly, such as a getter/setter method call rather than direct attribute access, faking overloading (which Python doesn't have or want), and using name-mangled `__foo` attributes to try to make private attributes (which Python also doesn't have or want).
Mike Graham
@Mike: Hey! I wrote the Tcl solution and that's definitely got slow antipatterns in it too (e.g., probing the stack to determine whether to read or write the fields!) but I believe in solving the problem as presented and not the one I'd rather have. :-)
Donal Fellows
To be fair to Donal's answer, it serves to demonstrate why UML-based design is *not* language-agnostic. That diagram specifies way too much implementation detail - so it's two different questions "how to implement this interface in Python", and "how would you actually provide in Python the functionality suggested by this interface"? For a more concrete example, see how the DOM interface ends up "translated" in different languages.
Steve Jessop
A: 

Go (my Go style is not very developed. Also, I don't have the compiler on this machine to test. Here goes anyway):

package main

import  "fmt"

type Fraction struct {
    numerator int
    denominator int
}

// Go doesn't have function/method overloading
func ( frac *Fraction ) SetNumerator( v int )  {
    frac.numerator = v
}
func( frac *Fraction ) SetDenominator( v int )  {
    frac.denominator = v
}
func(frac *Fraction ) Numerator() int {
    return frac.numerator
}
func( frac *Fraction ) Denominator() int {
    return frac.denominator
}
func( frac *Fraction ) Print()  {
    fmt.Printf("%d/%d\n",frac.Numerator(), frac.Denominator())
}

func main() {
    f:=&Fraction{}
    f.SetNumerator(1)
    f.SetDenominator(2)

    f.Print()
}
Steve Jessop
+8  A: 

I guess I'd actually want to write something like this in Java:

public final class Fraction implements Comparable<Fraction> {
    private final int num;
    private final int den;

    private Fraction(int num, int den) {
        if (den == 0) {
            throw new ArithmeticException();
        }
        int gcd = gcd(num, den); // To do...
        this.num = num/gcd;
        this.den = den/gcd;
    }
    public static Fraction of(int num, int den) {
        return new Fraction(num, den);
    }

    public int numerator() {
        return num;
    }
    public int denominator() {
        return den;
    }

    @Override public boolean equals(Object obj) {
        if (!(obj instanceof Fraction)) {
            return false;
        }
        Fraction other = (Fraction)obj;
        return this.num == other.num && this.den == other.den;
    }
    @Override public int hashCode() 
        int h = den;
        h = h*41 + num;
        return h;
    }
    @Override public String toString() {
        return num+"@"+den;
    }

    public int compareTo(Fraction other) {
        return Longs.compare( // To do...
            this.num*(long)other.den,
            other.num*(long)this.den
        );
    }
}

...

public static void main(String [] args) {
    Fraction fraction = Fraction.of(2, 5);
    System.out.println(fraction)

    // using the "getters"
    int num = fraction.numerator();
    int den = fraction.denominator();
}

There is a suggest that Java should have direct support to make immutable values simpler.

What actually get written:

public class Fraction implements Serializable {
    public int numerator, denominator;
}

(See java.awt.Point.)

Tom Hawtin - tackline
There are no setters for denominator and numerator though, how are we gonna dependency inject those values??
GreenieMeanie
@GreenieMeanie We are going to injection via the creation method, because we like doing the Right Thing. Are you with me?!
Tom Hawtin - tackline
I think we should create a fraction interface and another concrete class that allows it both ways so that we can dependency inject the values. Let's create a factory and update our XML files.
GreenieMeanie
@GreenieMeanie Please don't.
Tom Hawtin - tackline
+1  A: 

C# - Because you wanted to compare languages and I'm bored, here is a more java like way of defining the class that also works. Please note I wouldn't actually do it this way, @Muad'dib has the standard approach in C#. I'm just putting this in for completeness sake and so you see how close C# can be to Java with simple code like this. Note that C# will not let you name a field and method the same (no overloading between the fields and methods).

public class Fraction
{
    private int numerator;
    private int denominator;

    public int Numerator()
    {
        return numerator;
    }

    public void Numerator(int val)
    {
        numerator = val;
    }

    public int Denominator()
    {
        return denominator;
    }

    public void Denominator(int val)
    {
        denominator = val;
    }

    public void Print()
    {
        Console.WriteLine(numerator);
        Console.WriteLine(denominator);
    }
}
// in whatever your startup class is.
static void Main(string[] args)
{
    Fraction f = new Fraction();
    f.Numerator(2);
    f.Denominator(5);
    f.Print();
    // using the "getters"
    int n = f.Numerator();
    int d = f.Denominator();
}
Jim Leonardo
A: 

7Basic

CLASS Fraction
    FUNCTION SetNumerator (val AS INTEGER)
        numerator = val
    END FUNCTION
    FUNCTION SetDenominator (val AS INTEGER)
        denominator = val
    END FUNCTION

    FUNCTION GetNumerator ()
        RETURN numerator
    END FUNCTION
    FUNCTION GetDenominator ()
        RETURN denominator
    END FUNCTION

    FUNCTION print ()
        // print the data
    END FUNCTION

    DIM numerator AS INTEGER
    DIM denominator AS INTEGER
END CLASS

And to use the class:

DIM f AS FRACTION

f.SetNumerator( 5 )
f.SetDenominator( 5 )

f.print()
George Edison
You like I, forgot the get Functions
SeanJA
Does the OP want those too?
George Edison
They are part of the spec
SeanJA
+1  A: 

So, how would you defined the following class along with with its operations in your favorite programming language?

I wouldn't. The only useful thing this class can do is print itself. Exposing its numerator and denominator as properties don't provide you with anything more than named integers. I can do that by just typing var numerator = 69, no type def needed.

What you should do is make Fraction immutable, overload math operators, and create math functions for which there aren't operators (Math.Pow, for example).

However, because I'm lazy, I'm only going to provide an implementation for the first thing I said.

using System;

public class Fraction
{
    public Fraction(int numerator, int denominator)
    {
        this.numerator = numerator;
        this.denominator = denominator;
    }

    public void Print()
    {
        Console.WriteLine(numerator + "/" + denominator);
    }

    readonly int numerator;
    readonly int denominator;
}

static class EntryPoint
{
    static void Main()
    {
        var twoThirds = new Fraction(2, 3);
        twoThirds.Print();
    }
}
Sam Pearson
Forget about the semantics, this is not a *real* fraction class to be used on production or anything, just a language showcase.
OscarRyz
Maybe you should lighten up
Charlie Somerville
A: 

Python 3.x:

class Fraction:
    def __init__(self, num, denom):
        self.__numerator = num
        self.__denominator = denom

    def numerator(self, num=None):
        if num is not None:
            self.__numerator = num
            return None
        return self.__numerator

    def denominator(self, denom=None):
        if denom is not None:
            self.__denominator = denom
            return None
        return self.__denominator

    def __str__(self):
        return "{0}/{1}".format(self.__numerator, self.__denominator)

    # Printable representation of the Fraction instance (included for
    # debugging, hence the details provided and the difference between
    # the __repr__ and the __str__ definitions).
    def __repr__(self):
        return "{0}({1}, {2})".format(self.__class__,
                                      self.__numerator,
                                      self.__denominator)
Dustin
I thought one of the exciting new features of Python 3 was that everything inherits from `object` automatically.
Steve Jessop
@Steve Jessop: Edited.
Dustin
@Oscar Reyes: The __ prefixing the variable names is sort of like making them private in C++. Of course, anybody with access to your source code knows they're not private. I also do it to avoid confusing the variable with the function of a similar name.
Dustin
@Oscar: private members. Inside a class `Fraction`, the token `__numerator` is replaced with `Fraction__numerator`. So users have to go especially out of their way to break encapsulation and access the member. It's actively useful when you don't know (or care) what fields your parents or children have, and want to pick a field name that won't clash.
Steve Jessop
yuk, this is ugly!
Pavel Shved
@Pavel: to a C++ programmer it certainly has that "I've accidentally opened up vector.h, and I wish I hadn't" vibe to it ;-)
Steve Jessop
@Pavel: That's why functions shouldn't be used in Python when public variables can do the work. Many things are modifiable in Python that seem like they shouldn't be when coming from C++ (e.g. built-in identifiers to functions such as `int` can be reassigned to something else like in `int = 'Hello World!'`, which means that calling the `int` function after that will raise an exception, a TypeError in this case).
Dustin
Why do you use private variables here? This is not Java you don't need getters/setters; simple attributes will do (it doesn't change usage so you can always add them later if you must).
J.F. Sebastian
Not to mention that __named attributes aren't private in python, and it's useless to pretend that they are.
Aaron Gallagher
Having those numerator/denominator methods act as getters or setters depending on arguments passed is just bizarre. I know it's what the question asked for, but it's really not something you'd encounter in normal python code (in this case there's no real need to have accessors, but if there was you'd use a property or getters/setters with distinct names instead)
mzz
@mzz: it may be bizarre *in Python*, but I've seen it in Java and C++. It's very hard to answer the question, "how would you idiomatically write, in this language, something which is a completely artificial example in the first place?". As Mike Graham and others have pointed out, the answer depends on the point at which you cease suspending disbelief and just admit, "I wouldn't". The questioner asked for a method overloaded on the number of parameters: this answer gives that in Python. Others have already done a hatchet job on whether the question asks for something worthwhile ;-)
Steve Jessop
+8  A: 

Javascript:

function Fraction(numerator, denominator)
{
  var _numerator = numerator;
  var _denominator = denominator;

  var outputFunction = document.writeln;


    this.numerator = function(value)
    {
        if(value) _numerator = value;
        else return _numerator;
    }

    this.denominator = function(value)
    {
        if(value) _denominator = value;
        else return _denominator;
    }

    this.print = function()
    {
        outputFunction(this.numerator() + "/" + this.denominator());
    }
}

var f = new Fraction(1,2);
f.print();
f.numerator(5);
f.denominator(11);
f.print();

var n = f.numerator();
var d = f.denominator();

document.writeln(n + "/" + d);
el chief
+1 Nice _` ` ` `_
George Edison
Doesn't a cat dies every time you place the open brace like that in Javascript? I remember there was something about Javascript and placing the brace in a different line.
OscarRyz
Cats have 9 lives, and I only used 8 braces :)
el chief
Disgusting. Learn how to use prototypes.
trinithis
Prototypes are useful to minimize memory footprint, however there is only one instance of this class, so it is not an issue in this example. Unfortunately, prototypes prevent true encapsulation, in that you cannot have private member variables. Therefore, this implementation is more OOP. see http://www.crockford.com/javascript/private.html
el chief
@el chief, if it's a singleton, why didn't you use a factory function which returns an object literal? Crockford hates `new`, you know? :) And by the way, member visibility has nothing to do with OOP.
Ionuț G. Stan
+1  A: 

JavaScript:

<script type="text/javascript">

function print(str) {
    document.write(str + '<br/>\n');
}

var Fraction = function(n, d){
    var that = this; 
    var frac = [1, 0];

    if (n !== undefined)
        frac[0] = parseInt(n);
    if (d !== undefined)
        frac[1] = parseInt(d);

    function accessor(index) {
        return function(value){
            if (value === undefined)
                return frac[index];
            frac[index] = parseInt(value);
            return that; // Allow chaining
        };
    }


    that.numerator = accessor(0);
    that.denominator = accessor(1);
    that.toString = function(){
        return frac[0] + '/' + frac[1];
    };
    that.print = function(){
        print(that);
    };
    that.pie = function(){
        /* Does not support improper fractions. */
        var a = frac[0];
        var b = frac[1] - frac[0];
        print('<img src="http://chart.apis.google.com/chart?cht=p3&amp;chd=t:'
            +a+','+b+'&chs=300x150"/>');
    };

    return that;
}

var f = new Fraction(1, 3);
f.print();
f.numerator(2).denominator(5);
f.print();

print('numerator: ' + f.numerator());
print('denominator: ' + f.denominator());

(new Fraction(3,4)).pie();

</script>
Joey Adams
+4  A: 

Perl 5

Man, I'm super rusty on object-oriented Perl and I wouldn't say it's my favourite language by a long shot, but since no-one else has done it yet...

#!/usr/bin/perl

use strict;
use warnings;

package Fraction;
sub new {
    my $class = shift;

    my $this = {};
    $this->{numerator} = shift;
    $this->{denominator} = shift;
    bless($this, $class);
    return $this;
}

sub numerator {
    return shift->{numerator};
}
sub denominator {
    return shift->{denominator};
}
sub set_numerator { 
    my ($this, $num) = @_;
    $this->{numerator} = $num;
}
sub set_denominator {
    my ($this, $den) = @_;
    $this->{denominator} = $den;
}
sub str {
    my $this = shift;
    return sprintf("%s / %s", $this->numerator(), $this->denominator());
}


package Main;

my $f = Fraction->new(1, 2);
print $f->str(), "\n";
$f->set_numerator(2);
$f->set_denominator(5);
print $f->str(), "\n";
Mikesname
That's the spirit
OscarRyz
+13  A: 

Haskell

data Fraction = F { num :: Integer, den :: Integer }
                deriving (Show)
troutwine
Demominator? I think you have a typo there
Charlie Somerville
A bit! Thanks, the problem is now fixed.
troutwine
+7  A: 

Objective-C, using synthesized properties:

@interface Fraction : NSObject {
    int numerator;
    int denominator;
}

@property (assign) int numerator;
@property (assign) int denominator;
- (id)initWithNumerator:(int)theNumerator denominator:(int)theDenominator;
- (void) print;

@end

@implementation Fraction

@synthesize numerator, denominator; //implements getters and setters

- (id)initWithNumerator:(int)theNumerator denominator:(int)theDenominator {
    self = [super init];
    if (!self)
        return nil;

    numerator = theNumerator;
    denominator = theDenominator;

    return self;
}

- (id)init {
    return [self initWithNumerator:0 denominator:1];
}

- (NSString *) description { //equivalent of toString() in Java
    return [NSString stringWithFormat:@"%d/%d", self.numerator, self.denominator];
}    

- (void) print {
    NSLog(@"%@", self);
}

@end

int main(int argc, char **argv) {
    Fraction f = [[Fraction alloc] init];
    f.numerator = 2;
    f.denominator = 5;
    [f print];
    int n = f.numerator;
    int d = f.denominator;
    [f release];

    return 0;
}
eman
To give it a more Objective-C/Cocoa feel, perhaps an `initWithNumerator:denominator:` method as well?
dreamlax
+7  A: 

Common Lisp (which already has a rational type)

(defclass fraction ()
  (
   (numer :accessor numer :initarg :numer :initform 0 :type integer)
   (denom :accessor denom :initarg :denom :initform 1 :type integer)
   ) )

(defmethod print-object ((r fraction) stream)
  (format stream "~A/~A" (numer r) (denom r) ))

(defvar f (make-instance 'fraction :numer 2 :denom 5))
(print-object f t)
(defvar n (numer f))
(defvar d (numer d))

;; Not necessary, but somewhat useful
(defun make-fraction (&optional (n 0) (d 1) &rest initargs) 
  (declare (type integer n d))
  (apply #'make-instance 'fraction :numer n :denom d initargs))
(defvar half (make-fraction 1 2))
outis
+7  A: 

You know what you don't see anymore?

SIMULA

Begin
    Class Fraction (Numerator, Denominator) Integer Numerator, Denominator;
    Begin
        Procedure Print;
        Begin
            OutInt(Numerator,7);OutChar('/');OutInt(Denominator,7);OutImage
        End;
    End;

    Ref(Fraction) F;
    F :- New Fraction(2,3);
    F.Print
End;

Take with a pinch of salt. This is based on my 25 year old recollection.

uncle brad
There's something wrong with us, something very, very wrong with us. Something seriously wrong with us - we're programmers.
uncle brad
Cool! I've never seen Simula before. BTW: is this Simula I or Simula-67? Does it even matter in this instance?
Jörg W Mittag
Begin... End... ooohhh this reminds me of .. was it Pascal or Delphi?
BerggreenDK
@Jörg I thought you say having a class like this was idiotic! It may be idiotic but it's cool at the same time, which means that even you can learn something new with this question.
OscarRyz
I think that there's a good reason you don't see simula anymore ;)
RCIX
+1  A: 

PowerShell:

function Fraction {
  new-object PSObject | select numerator, denominator | 
    add-member -passthru -membertype scriptmethod -name print -value { 
      write-host "$($this.numerator)/$($this.denominator)"
  }
}

$obj = Fraction
$obj.numerator = 3
$obj.denominator = 5
$obj.print()
$i = $obj.numerator
$d = $obj.denominator
ssg
Hmm, this is object, not a class!
Gabriel Ščerbák
That rules out JavaScript too you know :)
ssg
+6  A: 

Another Javascript implementation, using prototype, getters and setters:

function Fraction(n, d) {
    this.numerator = n;
    this.denominator = d;
}

Fraction.prototype = {
    get numerator() { return this.numer; },
    set numerator(n) { this.numer = n; },
    get denominator() { return this.denom; },
    set denominator(d) { this.denom = d; },
    toString: function () {
        return this.numerator + '/' + this.denominator;
    }
};

var f = new Fraction();
f.numerator = 2;
f.denominator = 5;
f + ''
var n = f.numerator;
var d = f.denominator;
outis
I didn't know you could do that in JavaScript! What version do you need?
Joey Adams
@Joey - It's ECMAScript 5.
Jimmy Cuadra
+48  A: 

Punched Cards

*     *    *        *    *
*          *    *        *
      *    *    *
      *    *    *    *
*     *    *        *    *
*          *    *        *

Usage

   *  *    *    *    *    *
*          *    *        *
   *  *            *
                *    *
*     *    *        *     
*               *        *
Ben
i think you got a syntax error in the Usage -- 4th column...
RCIX
FUN answer! :o)
BerggreenDK
+1. Absolutely BRILLIANT. But you should have followed this format: http://www.cs.uiowa.edu/~jones/cards/format.html
JUST MY correct OPINION
-1 - This is NOT correct. You are assuming a DOS line ending - but you are using a Unix compiler :)
George Edison
@George - Oh snap!
Ben
You should totally drop that and try punchQuery. :)
Zach Johnson
I have some punch cards... anyone have anything that can read my punch cards after I fill them full of holes?
SeanJA
@SeanJA: Ya, there is something: http://www-03.ibm.com/ibm/history/exhibits/701/images/141505.jpg
George Edison
OK, hold on. At the risk of sounding like an inexperienced young whippersnapper, can somebody clear something up for me... is this real?
Dan Tao
@Dan Tao: I am going with no... but then again, I have used punch cards... once.
SeanJA
+1  A: 

Groovy:

class Fraction {
    def numerator, denomenator

    def print() {
        print "$numerator/$denomenator"
    }
}

def frac = new Fraction()
frac.numerator = 1
frac.denomenator = 2
frac.print()
def n = frac.numerator
def d = frac.denomenator
Stephen Swensen
+4  A: 

C#

    public class Fraction
    {
        public int Numerator { get; set; }

        private int _denominator;
        public int Denominator
        {
            get
            {
                return _denominator;
            }
            set
            {
                if (value != 0)
                    _denominator = value;
                else
                    throw new ArgumentException("Denominator must be non-zero.");
            }
        }


        public Fraction(int numerator, int denominator)
        {
            Numerator = numerator;
            Denominator = denominator;
        }

        public override string ToString()
        {
            return string.Format("{0}/{1}", Numerator, Denominator);
        }

        public static implicit operator double(Fraction f)
        {
            return f.Numerator / f.Denominator;
        }
Rodrick Chapman
Denominator must be *greater* than zero, eh? Not a fan of negative numbers? ;)
Dan Tao
I don't think you'd want to cast to double using integer division...
OedipusPrime
No love for the C# apparently...
SeanJA
@Dan Tao - opps, thanks...
Rodrick Chapman
@noblethrasher: Ha, just being a jerk, don't sweat it ;)
Dan Tao
+1  A: 

Lua: depends on the class library you use. If you use something like LOOP, then it looks like this:

require 'loop.simple'

local fraction = loop.simple.class {
    data = { -- have to do this because i canot define multiple things to be the same name in a given scope
        numerator = 0,
        denominator = 0,
    },
    fracPrint = function(self)
        print(self.data.numerator .. '/' .. self.data.denominator)
    end,
    numerator = function(self, value) -- note that this is not usually how things are defined in lua, but to match your "spec" i wrote these two functions like this
        if value then self.data.numerator = value else return self.data.numerator end
    end,
    denominator = function(self, value)
        if value then self.data.denominator = value else return self.data.denominator end
    end,
}

local myFraction = fraction()
myFraction:fracPrint()
myFraction:numerator(1)
myFraction:denominator(2)
myFraction:fracPrint()

local myNum = myFraction:numerator()
local myDen = myFraction:denominator()
print(myNum .. '/' .. myDen)
RCIX
+1  A: 

Not my favorite language but others were taken.

ActionScript:

package {
  public class Fraction {
    private var n:int;
    private var d:int;
    public Fraction( numerator:int , denominator:int ) { n = numerator; d = denominator; }
    public get numerator():int { return n; }
    public get denominator():int { return d; }
    public set numerator( numerator:int ) { n = numerator; }
    public set denominator( denominator:int ) { d = denominator; }
    public print() { trace( "" + n + "/" + d ); }
  }
}

var f:Fraction = new Fraction( 1 , 2 );
f.print();
drawnonward
+1  A: 

Wow, no love whatsoever for VB.NET, huh?

UPDATE: In deference to Konrad Rudolph, whose rep could beat the crap out of mine and steal its lunch money, here is a proposed VB.NET solution which takes liberties with the spec on the premise that a proper design would deviate from the requirements provided:

Public Class Fraction

    Private ReadOnly _numerator As Integer
    Public ReadOnly Property Numerator() As Integer
        Get
            Return _numerator
        End Get
    End Property

    Private ReadOnly _denominator As Integer
    Public ReadOnly Property Denominator() As Integer
        Get
            Return _denominator
        End Get
    End Property

    Sub New(ByVal numerator As Integer, ByVal denominator As Integer)
        _numerator = numerator
        _denominator = denominator
    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("{0} / {1}", _numerator, _denominator)
    End Function

End Class

Usage demo:

Sub Main()
    ' Fraction class is immutable; '
    ' numerator and denominator must be set in the constructor. '
    Dim f As New Fraction(2, 3)

    ' This is how a Fraction would be printed to the console. '
    Console.WriteLine(f.ToString())

    ' Numerator and Denominator properties are publicly '
    ' accessible, but cannot be modified. '
    Dim numerator As Integer = f.Numerator
    Dim denominator As Integer = f.Denominator
End Sub
Dan Tao
Looks sorta like Stewie `("{0} / {1}")`
SeanJA
@SeanJA: Ha, wow, true. How in the world did you make that connection, is what I'd like to know?!
Dan Tao
Not a very idiomatinc VB.NET solution, though. `Print` should definitely be `ToString`, everything else makes no sense. And a good class design would violate the specs by making the properties read-only and adding an appropriate constructor. We could even argue whether this should really be a `Structure` instead of a `Class` (but there’s a good case to be made against that).
Konrad Rudolph
@Konrad: All valid points, but ... did you read the question? I see you did: "...a good class design would violate the specs..." So should I have *not* answered the question, then? By the way, I think it's kind of presumptuous that everybody's saying, "This is a bad design" (you're certainly not the first -- just look at the comments to the question), just because the class is called `Fraction`. The OP never said, "This class would be used in a mathematical library." Suppose it's an educational program with fractions that display on flash cards? In that case would immutability really matter?
Dan Tao
@Konrad: As for how idiomatic the code is... I really can't respond to that, unfortunately, as my experience with VB.NET is limited to working with the team I'm currently a part of, and I don't think any of us comes from a VB culture. The properties I implemented with code snippets, and the `Print` method I wrote ... well, pretty much the most obvious way (to me). Maybe you could point out what a more idiomatic VB.NET solution would be?
Dan Tao
@Konrad: One final note: the `Print` method, based on the OP's code example, is clearly meant to actually *print* (i.e., display) the `Fraction` to some output device, not merely return a `String` representation of it (as a `ToString` function would).
Dan Tao
@Dan Tao: Several things. 1. Yes, as others have pointed out, the specs are bad. That’s not presumptuous, that’s a clear fact. 2. I’m not sure how using flash cards changes the immutability argument. 3. As for `Print`, have a look at the documentation of `ToString`. Yes, the OP specified that it should print something but a) that breaks SRP, as noted by Jörg, and b) the OP wanted solutions in different languages and that means working *in the context of that language*. So the result *will* be different designs, which is a good thing if we follow the OP’s purpose of showcasing differences.
Konrad Rudolph
@Konrad: All right, you win: I've changed the code to look a bit more like something you'd expect to see in some real VB code (or anyway, more like something *I* would write). About the flash card example, though: I feel everybody is saying this class must be immutable on the assumption it would actually be used *as a fraction*, e.g., passed around among functions that operate on fractions in a mathematical sense, such that nefarious bugs would surface as a result of mutability... (Cont.)
Dan Tao
@Konrad: But if it's just, you know, a flash card: 1 / 5 is what? And the user (a kid) picks 20%, hooray, correct, then set the numerator and denominator to 2 new values: 3 / 2 is what? The kid picks 150%, hooray, right again! What is the huge problem with the class design then? In this scenario, the `Fraction` class would not really represent a fraction in the mathematical sense -- more in the sense of the visual symbol that is displayed on a flash card.
Dan Tao
+4  A: 

(defrecord Fraction [numerator denominator])

This is a new Clojure feature, so there aren't any factory methods for creating an instance of the defrecord. If you're feeling verbose, you can do (defn make-fraction [numer denom] (Fraction. numer denom))

The fields can be accessed with keywords:

(:numerator instance-of-fraction)
(:denominator instance-of-fraction)

And toString is already implemented, so the normal print and println functions will work for it.

Setters are irrelevant as well, as they'd just be wrapping assoc:

(assoc instance-of-fraction :numerator 3) ; sets numerator to 3. Actually, returns a new instance of Fraction.
Rayne
+1  A: 

in REBOL

;; create the model object
    fraction: make object! [
      numerator: none
      denominator: none
      print: does [source self self]
      ]


;; create an instance:
    f: make fraction []
    f/numerator: 2
    f/denominator: 5

;; Or, in one line:
    f: make fraction [numerator: 2 denominator: 5]


;; using print, and seeing the console output:
    f/print
    >> self: make object! [
    >> numerator: 2
    >> denominator: 5
    >> print: func [][source self]
    >>    ]
Sunanda
this prints itself not the string "2/5" ?
ssg
Oops yes. I misunderstood the requirement. Thanks for clarifying. Correct code to print 2 / 5 is.....print: does [do get in system/words 'print [self/numerator "/" self/denominator]]
Sunanda
I'm fairly certain he didn't say *how* you have to print it. My example doesn't print it that way, but it does print it. I could override the implementation of toString in my example if he clarifies his post.
Rayne
+5  A: 

32-bit x86 assembly using MASM (as best as I can remember, and it calls printf() to do the printing):

.model flat

Fraction STRUCT
  numerator DWORD ?
  denominator DWORD ?
Fraction ENDS

.const
fraction_print_format db "%d/%d",0

.code

;void _stdcall Fraction_SetNumerator(Fraction*p,unsigned int v);
public _Fraction_SetNumerator
  pop ebx
  pop eax
  pop (Fraction ptr [eax]).numerator
  jmp ebx

;void _stdcall Fraction_SetDenominator(Fraction*p,unsigned int v);
public _Fraction_SetDenominato
  pop ebx
  pop eax
  pop (Fraction ptr [eax]).denominator
  jmp ebx

;int _stdcall Fraction_GetNumerator(const Fraction*p);
public _Fraction_GetNumerator
  pop ebx
  pop eax
  mov eax,(Fraction ptr [eax]).numerator
  jmp ebx

;int _stdcall Fraction_GetDenominator(const Fraction*p);
public _Fraction_GetDenominator
  pop ebx
  pop eax
  mov eax,(Fraction ptr [eax]).denominator
  jmp ebx

;void _stdcall Fraction_Print(const Fraction*p);
public _Fraction_Print
  mov eax,[esp+4]
  push (Fraction ptr [eax]).denominator
  push (Fraction ptr [eax]).numerator
  push offset fraction_print_format
  call _printf
  add esp,12
  retf 8
BY
Is calling printf the easy way out? (I really have no idea and I am curious)
SeanJA
Well, it's not any easier than other languages using their own built-in printing functions. Of course you can call OS routines directly, on Windows that would be wsprintf() and WriteConsole() for this example.
BY
+1  A: 

In Tcl, the class definition can be:

oo::class create Fraction {
    variable numerator denominator
    constructor {} {
        set numerator [set denominator 0]
    }
    method numerator {{newNum ""}} {
        set numerator {*}[lrange [info level 0] 2 end]
    }
    method denominator {{newNum ""}} {
        set denominator {*}[lrange [info level 0] 2 end]
    }
    method print {} {
        puts "$numerator/$denominator"
    }
}

I wouldn't normally write variable accessors like that, as it is quite a bit slower than using something less convoluted, but it does allow the original problem specification to be tackled.

The code to use it according to the original pattern:

set f [Fraction new]
$f numerator 2
$f denominator 5
$f print
set n [$f numerator]
set d [$f denominator]
puts "n=$n, d=$d"
Donal Fellows
+3  A: 

In Scheme, using closure:

(define (fraction n d)
  (lambda (message . args)
    (case message
      ((numerator!) (set! n (car args)))
      ((denominator!) (set! d (car args)))
      ((numerator) n)
      ((denominator) d)
      ((print) (display n) (display "/") (display d)))))

Sample usage:

> (define f (fraction 10 3))
> (f 'numerator)
10
> (f 'denominator)
3
> (f 'numerator! 11)
> (f 'denominator! 2)
> (f 'print)
11/2
Vijay Mathew
+4  A: 

In Ada (this could be improved I'm sure):

Specification:

package Fraction is

   type Fraction is private;
   procedure Print (This : Fraction);
   procedure Set_Numerator (This : in out Fraction;
                            A_Numerator : in Integer);
   procedure Set_Denominator (This : in out Fraction;
                              A_Denominator : in Integer);
   function Get_Numerator   (This : Fraction) return Integer;
   function Get_Denominator (This : Fraction) return Integer;

private
   type Fraction is tagged
      record 
         numerator : Integer;
         denominator : Integer;
      end record ;

end Fraction;

Body:

with Ada.Text_IO; use Ada.Text_IO;

package body Fraction is

   function Get_Numerator (This : Fraction) return Integer is
   begin
      return This.Numerator;
   end Get_Numerator;

   function Get_Denominator (This : Fraction) return Integer is
   begin
      return This.Denominator;
   end Get_Denominator;

   procedure Set_Numerator (This : in out Fraction;
                            A_Numerator : in Integer) is
   begin
      This.Numerator := A_Numerator;
   end Set_Numerator;

   procedure Set_Denominator (This : in out Fraction;
                              A_Denominator : in Integer) is
   begin
      This.Denominator := A_Denominator;
   end Set_Denominator;

   procedure Print (This : Fraction) is
   begin
      Put_Line (Integer'Image(This.Numerator));
      Put_Line (Integer'Image(This.Denominator));
   end Print;

end Fraction;

Usage:

with Fraction; use Fraction;

procedure Main
is
  f : Fraction.Fraction;
  n, d : Integer;
begin
  Set_Numerator (f, 2);
  Set_Denominator (f, 3);
  Print(f);
  n := Get_Numerator(f);
  d := Get_Denominator(f);
end Main;
+1  A: 

Perl 5 (w/o Moose, but with a bit of metaprogramming)

package Fraction;
use strict;

sub new {
   my $class = shift;
   bless { numerator => shift, denominator => shift }, $class;  
}

# accessor generator
for my $member (qw/numerator denominator/) {
    *{$member} = sub {
        my $self = shift;
        $self->{$member} = shift if [email protected];
        return $self->{$member};
    }
}

sub print {
    my $self = shift; 
    print "$self->{numerator}/$self->{denominator}\n";
}

Usage

use Fraction;

$f = Fraction->new();
$f->numerator(2);
$f->denominator(5);
$f->print();

$n = $f->numerator();
$d = $f->denominator();
kixx
+2  A: 

Fortran 2003 =)

Math.f90

MODULE Math

  IMPLICIT NONE

  PRIVATE

  PUBLIC :: Math_Fraction

  TYPE :: Math_Fraction
    PRIVATE
    INTEGER :: numerator_
    INTEGER :: denominator_
  CONTAINS
    PROCEDURE, PASS :: set_numerator
    PROCEDURE, PASS :: set_denominator
    PROCEDURE, PASS :: numerator
    PROCEDURE, PASS :: denominator
    PROCEDURE, PASS :: print
  END TYPE Math_Fraction

  CONTAINS

    SUBROUTINE set_numerator(this, numerator)
      CLASS(Math_Fraction) :: this
      INTEGER, INTENT(IN) :: numerator

      this%numerator_ = numerator
    END SUBROUTINE set_numerator

    SUBROUTINE set_denominator(this, denominator)
      CLASS(Math_Fraction) :: this
      INTEGER, INTENT(IN) :: denominator

      this%denominator_ = denominator
    END SUBROUTINE set_denominator

    FUNCTION numerator(this) RESULT(result)
      CLASS(Math_Fraction) :: this
      INTEGER :: result

      result = this%numerator_
    END FUNCTION numerator

    FUNCTION denominator(this) RESULT(result)
      CLASS(Math_Fraction) :: this
      INTEGER :: result

      result = this%denominator_
    END FUNCTION denominator


    SUBROUTINE print(this)
      CLASS(Math_Fraction) :: this

      WRITE (*, *) this%numerator_, '/', this%denominator_
    END SUBROUTINE print

END MODULE Math

Main.f90

PROGRAM Main

  USE Math

  IMPLICIT NONE

  TYPE(Math_Fraction) :: f

  CALL f%set_numerator(2)
  CALL f%set_denominator(5)

  WRITE (*, *) f%numerator(), '/', f%denominator()

  CALL f%print

END PROGRAM Main

Compile using gfortran 4.5:

$ gfortran -o app Math.f90 Main.f90
$ ./app
           2 /           5
           2 /           5
kemiisto
+4  A: 

Surprising no one posted this yet: Pascal (Object Pascal dialect)

program fractions;

type
    { Type declaration }
    Fraction = object

        private
            numerator : integer;
            denominator: integer;


        public
            procedure setNumerator (value : integer);
            function  getNumerator : integer;
            procedure setDenominator (value : integer);
            function  getDenominator : integer; 

            procedure print;
        end;


{ numerator setter }
procedure Fraction.setNumerator (value : integer);
begin
    self.numerator := value
end;


{ numerator getter }
function Fraction.getNumerator : integer;
begin
    getNumerator := numerator;
end;


{ denominator setter }
procedure Fraction.setDenominator (value : integer);
begin
    self.denominator := value;
end;


{ denominator getter }
function Fraction.getDenominator : integer;
begin
    getDenominator := denominator;
end;


{ print fraction on screen }
procedure Fraction.print;
begin
    write (self.numerator);
    write (' / ');
    write (self.denominator);
    writeln;
end;


{ Main program }
{ BTW, for those who never programmed Pascal before, those are comments;) }   
var
    f : Fraction;
    n,d : integer;

begin
    f.setNumerator (2);
    f.setDenominator (5);
    f.print;

    n := f.getNumerator;
    d := f.getDenominator;
end.
el.pescado
+1 Ooh.. the old Pascal.. :'( This was the first programming language I learn.
OscarRyz
+1  A: 

Some more Perl examples, since there's more than one way to do it:

the short way:

package Fraction;
    sub new         {shift; bless [@_]}
    sub numerator   {@_ > 1 ? $_[0][0] = $_[1] : $_[0][0]}
    sub denominator {@_ > 1 ? $_[0][1] = $_[1] : $_[0][1]}
    sub print       {print "$_[0][0]/$_[0][1]\n"}

the classical way:

package Fraction;
    sub new {
        my $pkg = shift;
        bless [@_] => $pkg
    }
    sub numerator {
        my $self = shift;
        @_ ? $$self[0] = shift : $$self[0]
    }
    sub denominator {
        my $self = shift;
        @_ ? $$self[1] = shift : $$self[1]
    }
    sub print {
        my $self = shift;
        print "$$self[0]/$$self[1]\n"
    }

a macro/function way:

package Fraction;
    sub self {$_[0]}
    sub arg1 {$_[1]}
    sub get  {@_ == 1}
    sub num  {0}
    sub den  {1}

    sub new {shift; bless [@_]}
    sub numerator {
        &get and &self->[num]
              or &self->[num] = &arg1
    }
    sub denominator {
        &get and &self->[den]
              or &self->[den] = &arg1
    }
    sub print {print &self->[num] .'/'. &self->[den] ."\n"}

to run:

my $fract = Fraction->new(2, 5);

$fract->print;

$fract->numerator(1);
$fract->denominator(4);

print $fract->denominator, "\n";

$fract->print;

and with an lvalue calling style:

package Fraction;
    sub new {shift; bless [@_]}
    sub numerator   :lvalue {$_[0][0]}
    sub denominator :lvalue {$_[0][1]}
    sub print {print &numerator .'/'. &denominator ."\n"}

package main;

$fract = Fraction->new(2, 5);

$fract->print;

$fract->numerator   = 3;
$fract->denominator = 6;

$fract->print;
Eric Strom
+3  A: 

Scala

It can be as simple as this:

case class Fraction(var num: Int, var den: Int) {
  def print = println(num + "/" + den)
}

or, if you want setter and getter methods:

case class Fraction {
  private var _num: Int
  private var _den: Int

  def this(num: Int, den: Int) {
    _num = num
    _den = den
  }

  def num = _num
  def den = _den

  def num_=(num: Int) {
    _num = num
  }

  def den_=(den: Int) {
    _den = den
  }

  def print = println(_num + "/" + +den)
}

and some code to test it:

object FractionTester extends Application {
  val f = Fraction(2, 5)

  f.print

  val n = f.num
  val d = f.den
}

(note: I've only just typed this code in here, I haven't checked to see if it works properly or even compiles)

Zoltan
A: 
class Fraction:
    def __init__(self, numerator, denominator):
        self.numerator = numerator
        self.denominator = denominator

    def __str__(self):
        return "%(numerator)s/%(denominator)s" % self.__dict__

    def __add__(self, other):
        #TODO: check other's type
        return Fraction(self.numerator + other.numerator,
                        self.denominator + other.denominator)

if __name__ == '__main__':
    print Fraction(1, 2) + Fraction(3, 4)
Rho
+1  A: 

Perl6


(but i'm not really sure, this was as much a learning experience for me as it is for the OP. And I wasn't able to test it... corrections & suggestions welcome!)

use v6;

class Fraction {
   has $.numerator;
   has $.denominator;

   method Str () {
      "$.numerator/$.denominator"
   }
}

main: {
   my $f = Fraction.new(
      numerator => 1,
      denominator => 2,
   );   
   $f.say;

   $f.numerator = 2;
   $f.denominator = 3;

   $f.say;
}
qbxk
+3  A: 

AppleScript:

on makeFraction(n, d)
    script Fraction
        property numerator : n
        property denominator : d
        on asString()
            return (numerator as string) & "/" & denominator as string
        end asString
        on print {}
            display dialog asString()
        end print

        -- Just because we can
        on pronunciation()
            if denominator is 2 then
                if numerator is 1 then
                    return (numerator as string) & " half"
                else
                    return (numerator as string) & " halves"
                end if
            else if numerator is 1 then
                return asString() & "th"
            else
                return asString() & "ths"
            end if
        end pronunciation
        on say
            continue say pronunciation()
        end say
    end script
    return Fraction
end makeFraction

set f to makeFraction(0, 1)
set numerator of f to 2
set denominator of f to 5
tell f to print {}
tell f to say it -- "it" is meaningless here, but can be included for readability
set n to numerator of f
set d to denominator of f
outis
A: 

This is MATLAB (TIOBE #20). Its OO is pretty new, only 2 years old, previously it had crippled pseudo-OO with only value "classes". In my opinion they borrowed heavily from python.

classdef (ConstructOnLoad=true) Fraction < handle
    %# Fraction Class
    properties
        numerator
        denominator
    end

    methods
        function obj = Fraction(num, den)
            %# Fraction(Num,Den) - Constructor for Fraction class
            %# set default values for num and den.
            if nargin<2, den = 1; end
            if nargin<1, num = 0; end

            %# set object properties
            obj.numerator = num;
            obj.denominator = den;
        end

        %# Setter for _denominator_ property
        %# Error checking. One should not be able to set denominator to zero
        function set.denominator(obj,den)
            if den == 0, error('Error: denominator was set to zero'); end
            obj.denominator = den;
        end

        %# overload  MATLAB's disp function for printing
        function disp(obj)
            disp([num2str(obj.numerator),'/',num2str(obj.denominator)]); 
        end
    end
end

>> f = Fraction(2,3)

f = 
2/3

>> f.numerator = 2;
>> f.denominator = 5;
>> disp(f)
f =
2/5
>> n = f.numerator
>> d = d.numerator
Mikhail
+5  A: 

C - Better abstraction and encapsulation than the others

I'm not satisfied with the versions in C that I've seen. We should use an abstract typedef and private struct thusly:

fraction.h

#ifndef FRACTION_H
#define FRACTION_H

#ifdef __cplusplus
extern "C" {
#endif

struct Fraction_private;
typedef struct Fraction_private Fraction;

Fraction *FractionCreate(int numerator, int denominator);
void FractionDestroy(Fraction *fraction);
int FractionGetNumerator(Fraction *fraction);
int FractionGetDenominator(Fraction *fraction);
void FractionPrint(Fraction *fraction);

#ifdef __cplusplus
} // extern
#endif

#endif

fraction.c

#include "fraction.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>

struct Fraction_private {
        int numerator;
        int denominator;
};

Fraction *FractionCreate(int numerator, int denominator) {
        Fraction *result = malloc(sizeof(*result));
        result->numerator = numerator;
        result->denominator = denominator;
        return result;
}

void FractionDestroy(Fraction *fraction) {
        free(fraction);
}

int FractionGetNumerator(Fraction *fraction) {
        assert(fraction);
        return fraction->numerator;
}

int FractionGetDenominator(Fraction *fraction) {
        assert(fraction);
        return fraction->denominator;
}

void FractionPrint(Fraction *fraction) {
        assert(fraction);
        printf("%d/%d", fraction->numerator, fraction->denominator);
}

Example use:

#include "fraction.h"
#include <stdio.h>

int main() {
        Fraction *f = FractionCreate(2, 4);
        printf("Numerator is %d, denominator is %d\n",
                FractionGetNumerator(f),
                FractionGetDenominator(f));

        printf("Using the print function: ");
        FractionPrint(f);
        printf("\n");

        FractionDestroy(f);
        return 0;
}

Now this looks much cleaner and abstract doesn't it? In fact, when you get down to it, this C is very much like object-oriented languages, just with a different syntax. Private members are inaccessible, and we can only manipulate the type using the predefined functions. We just happen to pass an explicit 'this' argument to each function.

Of course, in a real application a datatype this simple would probably be implemented as a struct on the stack like other solutions have done. But I though this would be nice for people to see that C can in fact do some nice abstract types.

Mike Weller
I disagree with mallocing everything in C, so I think this is if anything too abstract for many purposes. It makes the point, though, and if you needed binary compatibility with future versions of fraction.c then of course it's the way to go. It's the model followed by (for example) `FILE*` but not by (for example) `pthread_mutex_t`
Steve Jessop
@Mike: A few questions. 1) Is this an example of opaque types? 2) Why the need to wrap the header in the 'extern "C" { }'? Aren't these declarations needed if we compile with g++? 3) Would you keep the assert()'s in production code? 4) I assume you would make fraction.c a library to completely hide the implementation?
SiegeX
Yes, this is an example of opaque types.extern "C" is just a habit of mine when writing libraries. It means you can use this with a C++ compiler safely.I pretty much always keep assertions enabled in release code. If there are asserts in performance-critical sections I will use a different assert macro which I disable for release. And yeah if this is a library you would compile it to a static/dynamic library to hide the implementation fully.
Mike Weller
+2  A: 

UML:

UML class diagram

mouviciel
+1  A: 

Here's another quick PHP implementation. Although the other one was perfectly correct and a great example, it became slightly messy in adhering strictly to the UML so I separated the getters and setters.

<?php

class Fraction {

    private $numerator;
    private $denominator;

    public function setNumerator($num) {
        $this->numerator = $num;
    }

    public function setDenominator($den) {
        $this->denominator = $den;
    }

    public function getNumerator() {
        return $this->numerator;
    }

    public function getDenominator() {
        return $this->denominator;
    }

    public function __toString() {
        return sprintf('%d/%d', $this->numerator, $this->denominator);
    }

}

?>

And here is some example usage:

<?php

    $frac = new Fraction();

    $frac->setNumerator(2);
    $frac->setDenominator(4);

    // Prints 2/4
    echo $frac;

?>
WilliamMartin
+3  A: 

This is how it would look in idiomatic Scala:

case class Fraction(numerator: Int, denominator: Int) {
  override def toString = numerator + "/" + denominator
}

object FractionInAction {
  def main(args: Array[String]): Unit = {
    val f = Fraction(2, 5) 
    val n = f.numerator
    val d = f.denominator
    println(f)  // prints "2/5"

    // Getting modified copy
    val f1 = f copy (numerator = f.numerator + 1)
    println(f1) // prints "3/5"
  }
}

PS: I am aware that my Fraction class is immutable and thus doesn't follow the specification. See @Zoltan's answer for non-idiomatic but in-accordance-with-spec Scala solution.

missingfaktor
+1  A: 

Fun with Ruby

vim fraction.rb

class Fraction
  attr_accessor :numerator
  attr_reader   :denominator

  def initialize(numerator=0, denominator=1)
    @numerator = numerator
    self.denominator = denominator
  end 

  def denominator=(number)
    fail 'Only Chuck Norris can divide by zero!' if number == 0
    @denominator = number
  end 

  def +(other)
    Fraction.new(@numerator   * other.denominator +
                 @denominator * other.numerator,

                 @denominator * other.denominator)
  end 

  #...

  def to_s
    "#{@numerator}/#{@denominator}"
  end 
end

def start_fun
  Fixnum.send :alias_method, :old_div, :/
  Fixnum.send :define_method, :/ do |other|
    Fraction.new(self, other)
  end 
end

def go_back_to_normal
  Fixnum.send :alias_method, :/, :old_div
end

irb -r fraction.rb

start_fun
puts 10/5

=> 10/5

puts 1/2 + 3/4 + 5/6

=> 100/48

go_back_to_normal
puts 10/5

=> 2

toksaitov.d
+3  A: 

LOL

HAI
CAN HAS STDIO?

LET ME SHOW U MAI FARCTION
I HAS A NUMBAR ITZ "NOM" ALWAIZ
I HAS A NUMBAR ITZ "NOMNOM" ALWAIZ
KTHX

KTHXBYE
HAI

I HAS A MUDKIP ITZ A FARCTION
LOL MUDKIP NOM R 2
LOL MUDKIP NOMNOM R 5

MUDKIP SEZ NOM "/" NOMNOM
KTHX

KTHXBYE
Superstringcheese
+1 for most hilarious implementation!
A. Levy