views:

490

answers:

13

Hello,

I am currently looking for a programming language to write a math class in. I know that there are lots and lots of them everywhere around, but since I'm going to start studying math next semester, I thought this might be a good way to get a deeper insight in to what I've learned.

Thanks for your replys.

BTW: If you are wondering what I wanted to ask:

"Is there a strongly typed programming language which allows you to define new operators?"

+10  A: 

Maybe Haskell? Allows you to define arbitrary infix operators.

EFraim
+8  A: 

Well, you can redefine a fixed set of operators in many languages, like C++ or C#. Others, like F# or Scala allow you to define even new operators (even as infix ones) which might be even nicer for math-y stuff.

Joey
+7  A: 

Ted Neward wrote a series of article on Scala aimed at Java developers, and he finished it off by demonstrating how to write a mathematical domain language in Scala (which, incidentally, is a statically-typed language)

Part 1

Part 2

Part 3

skaffman
I think a downside of Scala would be inability to redefine precedence and associativity. These are fixed (defined by the first and last character of the method name).
Kevin Peterson
Yeah, that does smell a bit.
skaffman
+3  A: 

In C++ you can define operators that work on other classes, but I don't think other primitive types like ints since they can't have instance methods. You could either make your own number class in C++ and redefine ALL the operators, including + * etc.

To make new operators on primitive types you have to turn to functional programming (it seems from the other answers). This is fine, just keep in mind that functional programming is very different from OOP. But it will be a great new challenge and functional programming is great for math as it comes from lambda calc. Learning functional programming will teach you different skills and help you greatly with math and programming in general. :D

good luck!

CrazyJugglerDrummer
+16  A: 

Like EFraim said, Haskell makes this pretty easy:

% ghci
ghci> let a *-* b = (a*a) - (b*b)
ghci> :type (*-*)
(*-*) :: (Num a) => a -> a -> a
ghci> 4 *-* 3
7
ghci> 1.2 *-* 0.9
0.6299999999999999
ghci> (*-*) 5 3
16
ghci> :{
          let gcd a b | a > b     = gcd (a - b) b 
                      | b > a     = gcd a (b - a) 
                      | otherwise = a
      :}
ghci> :type gcd
gcd :: (Ord a, Num a) => a -> a -> a
ghci> gcd 3 6
3
ghci> gcd 12 11
1
ghci> 18 `gcd` 12
6

You can define new infix operators (symbols only) using an infix syntax. You can then use them as infix operators, or enclose them in parens to use them as a normal function.

You can also use normal functions (letters, numbers, underscores and single-quotes) as operators by enclosing them in backticks.

rampion
does it let you tinker with precedence?
skaffman
Yup! Use `infixr` and `infixl` : http://www.zvon.org/other/haskell/Outputsyntax/fixityQdeclaration_reference.html
rampion
+1  A: 

Eiffel allows you to define new operators.

http://dev.eiffel.com

+2  A: 

Ada has support for overriding infix operators: here is the reference manual chapter.

Unfortunately you can't create your own new operators, it seems you can only override the existing ones.

type wobble is new integer range 23..89;

function "+" (A, B: wobble) return wobble is
begin
   ...
end "+";

Ada is not a hugely popular language, it has to be said, but as far as strong typing goes, you can't get much stronger.

EDIT:

Another language which hasn't been mentioned yet is D. It also is a strongly typed language, and supports operator overloading. Again, it doesn't support user-defined infix operators.

From http://www.digitalmars.com/d/1.0/rationale.html

Why not allow user definable operators?

These can be very useful for attaching new infix operations to various unicode symbols. The trouble is that in D, the tokens are supposed to be completely independent of the semantic analysis. User definable operators would break that.

Mike Houston
+2  A: 

Inasmuch as the procedure you apply to the arguments in a Lisp combination is called an “operator,” then yeah, you can define new operators till the cows come home.

Cirno de Bergerac
+1  A: 

I think you should probably think deeply about why you want to use this feature. It seems to me that there are much more important considerations when choosing a language.

I can only think of one possible meaning for the word "operator" in this context, which is just syntactic sugar for a function call, e.g. foo + bar would be translated as a call to a function +(a, b).

This is sometimes useful, but not often. I can think of very few instances where I have overloaded/defined an operator.

As noted in the other answers, Haskell does allow you to define new infix operators. However, a purely functional language with lazy evaluation can be a bit of a mouthful. I would probably recommend SML over Haskell, if you feel like trying on a functional language for the first time. The type system is a bit simpler, you can use side-effects and it is not lazy.

F# is also very interesting and also features units of measure, which AFAIK is unique to that language. If you have a need for the feature it can be invaluable.

Off the top of my head I can't think of any statically typed imperative languages with infix operators, but you might want to use a functional language for math programming anyway, since it is much easier to prove facts about a functional program.

You might also want to create a small DSL if syntax issues like infix operators are so important to you. Then you can write the program in whatever language you want and still specify the math in a convenient way.

Jørgen Fogh
The C++ boost library "Units" provides compile-time dimensional analysis similar to the F# units of measure.
Hans Malherbe
+1  A: 

Both ocaml and f# have infix operators. They have a special set of characters that are allowed within their syntax, but both can be used to manipulate other symbols to use any function infix (see the ocaml discussion).

nlucaroni
A: 
Alex
Yeah that is right but you cannot define new operators, so that you are limited to +,-,*,/,the comparison operators and some more. But what if you have two sets and you want to get the union of the two? Should you really have to go and define a static function set.union(setA, setB)?
niklasfi
A: 

What do you mean by strong typing? Do you mean static typing (where everything has a type that is known at compile time, and conversions are restricted) or strong typing (everything has a type known at run time, and conversions are restricted)?

I'd go with Common Lisp. It doesn't actually have operators (for example, adding a and b is (+ a b)), but rather functions, which can be defined freely. It has strong typing in that every object has a definite type, even if it can't be known at compile time, and conversions are restricted. It's a truly great language for exploratory programming, and it sounds like that's what you'll be doing.

David Thornley
+1  A: 

Ruby does.

require 'rubygems'
require 'superators'

class Array
  superator "<---" do |operand|
    self << operand.reverse
  end
end

["jay"] <--- "spillihp"
Stefan Monov