是否有强类型编程语言允许您定义新的运算符?

时间:2009-07-26 12:53:16

标签: math programming-languages operators

我目前正在寻找一种编程语言来编写数学课。我知道周围有很多很多,但是因为我将在下学期开始学习数学,我认为这可能是一个更好地了解我所学到的知识。

感谢您的回复。

顺便说一句:如果你想知道我想问的是什么:

“是否有强类型编程语言允许您定义新的运算符?”

13 个答案:

答案 0 :(得分:19)

Like EFraim said,Haskell让这很简单:

% 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

您可以使用中缀语法定义新的中缀运算符(仅符号)。然后你可以使用 它们作为中缀运算符,或将它们包含在parens中以将它们用作正常函数。

您还可以使用普通函数(字母,数字,下划线和单引号)作为运算符 把它们放在反叛中。

答案 1 :(得分:10)

好吧,您可以使用多种语言重新定义一组固定的运算符,例如C++C#。其他的,比如F#Scala,你甚至可以定义新的运算符(即使是中缀运算符),这些运算符甚至可以更好地用于数学运算。

答案 2 :(得分:9)

也许Haskell?允许您定义任意中缀运算符。

答案 3 :(得分:8)

Ted Neward写了一系列关于Scala的文章,针对Java开发人员,他通过演示如何在Scala中编写数学领域语言(顺便提一下,这是一种静态类型语言)来完成它。

Part 1

Part 2

Part 3

答案 4 :(得分:3)

在C ++中,您可以定义适用于其他类的运算符,但我不认为其他原始类型如int,因为它们不能有实例方法。您可以在C ++中创建自己的数字类,并重新定义所有运算符,包括+ *等。

要在原始类型上创建新的运算符,您必须转向函数式编程(从其他答案看来)。这很好,请记住,函数式编程与OOP非常不同。但这将是一个伟大的新挑战,函数式编程对数学很有用,因为它来自lambda calc。学习函数式编程将教会您不同的技能,并通常帮助您进行数学和编程。 :d

祝你好运!

答案 5 :(得分:2)

Eiffel允许您定义新的运算符。

http://dev.eiffel.com

答案 6 :(得分:2)

Ada支持覆盖中缀运营商:这里是reference manual chapter

不幸的是,您无法创建自己的新运算符,您似乎只能覆盖现有运算符。

type wobble is new integer range 23..89;

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

Ada不是一种非常受欢迎的语言,不得不说,但就强类型而言,你不可能变得更强大。

修改

另一种尚未提及的语言是D。它也是一种强类型语言,并支持operator overloading。同样,它不支持用户定义的中缀运算符。

来自http://www.digitalmars.com/d/1.0/rationale.html

  

为什么不允许用户定义运营商?

     

这些对于将新的中缀操作附加到各种unicode符号非常有用。麻烦的是,在D中,令牌应该完全独立于语义分析。用户可定义的运营商会打破这种局面。

答案 7 :(得分:2)

因为你应用于Lisp组合中的参数的过程被称为“操作符”,所以是的,你可以定义新的操作符直到奶牛回家。

答案 8 :(得分:2)

ocaml和f#都有中缀运算符。它们在语法中有一组特殊的字符,但两者都可用于操纵其他符号以使用任何函数中缀(参见ocaml discussion)。

答案 9 :(得分:1)

我认为您应该深入思考为什么要使用此功能。在我看来,选择一种语言时有更重要的考虑因素。

在这种情况下,我只能想到“运算符”这个词的一个可能含义,它只是函数调用的语法糖,例如: foo + bar将被翻译为对函数+(a, b)的调用。

这有时很有用,但不常见。我可以想到很少有我重载/定义运算符的实例。

如其他答案中所述,Haskell允许您定义新的中缀运算符。然而,具有懒惰评估的纯函数语言可能有点拗口。如果您想第一次尝试使用函数式语言,我可能会推荐Sask而不是Haskell。类型系统稍微简单一点,你可以使用副作用而且它不是懒惰的。

F#也很有趣,还有units of measure,其中AFAIK是该语言独有的。如果您需要该功能,它可能是非常宝贵的。

在我的脑海中,我无法想到使用中缀运算符的任何静态类型的命令式语言,但你可能想要使用函数式语言进行数学编程,因为它更容易证明关于函数式程序的事实

如果像中缀运算符这样的语法问题对您来说非常重要,您可能还想创建一个小型DSL。然后你可以用你想要的任何语言编写程序,并且仍然可以方便地指定数学。

答案 10 :(得分:1)

强类型是什么意思?你的意思是静态类型(其中一切都有编译时已知的类型,转换受到限制)或强类型(一切都在运行时已知类型,并且转换受到限制)?

我会选择Common Lisp。它实际上没有运算符(例如,添加a和b是(+ a b)),而是函数,可以自由定义。它具有强大的类型,即每个对象都有一个明确的类型,即使它在编译时无法知道,并且转换也受到限制。它是探索性编程的真正优秀语言,听起来就像你将要做的那样。

答案 11 :(得分:1)

Ruby does.

require 'rubygems'
require 'superators'

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

["jay"] <--- "spillihp"

答案 12 :(得分:0)

您可以通过运算符重载实际执行C#所需的操作。

实施例:

 public static Complex operator -(Complex c)
 {
    Complex temp = new Complex();
    temp.x = -c.x;
    temp.y = -c.y;
    return temp;
 }

public static Complex operator -(Complex c) { Complex temp = new Complex(); temp.x = -c.x; temp.y = -c.y; return temp; }