2009-07-26 10 views
7

Attualmente sto cercando un linguaggio di programmazione per scrivere un corso di matematica. So che ce ne sono molti e molti dappertutto, ma dato che inizierò a studiare matematica il prossimo semestre, ho pensato che potesse essere un buon modo per avere una visione più profonda di ciò che ho imparato.Esiste un linguaggio di programmazione fortemente tipizzato che consente di definire nuovi operatori?

Grazie per le vostre risposte.

BTW: Se vi state chiedendo quello che volevo chiedere: "C'è un linguaggio di programmazione fortemente tipizzato, che permette di definire nuovi operatori"

+0

Definire "operatore". – Svante

+2

"Operatore" è un termine ben definito. –

risposta

19

Like EFraim said, Haskell rende questo abbastanza facile:

 
% 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 

È possibile definire nuovi operatori infissi (simboli solo) utilizzando una sintassi infisso. È quindi possibile utilizzare come operatori infissi o racchiuderli in parentesi per utilizzarli come una funzione normale.

È inoltre possibile utilizzare le normali funzioni (lettere, numeri, trattini bassi e virgolette singole) come operatori racchiudendoli in apici inversi.

+0

ti fa armeggiare con la precedenza? – skaffman

+2

Sì! Usa 'infixr' e' infixl': http://www.zvon.org/other/haskell/Outputsyntax/fixityQdeclaration_reference.html – rampion

9

Forse Haskell? Permette di definire operatori arbitrari di infissi.

10

Bene, è possibile ridefinire un insieme fisso di operatori in molte lingue, ad esempio C++ o C#. Altri, come F# o Scala consentono di definire anche nuovi operatori (anche quelli infix) che potrebbero essere ancora più interessanti per le cose matematiche.

8

Ted Neward ha scritto una serie di articoli su Scala volto a sviluppatori Java, e ha finito fuori dimostrando come scrivere un linguaggio dominio matematico a Scala (che, per inciso, è un linguaggio staticamente tipizzato)

Part 1

Part 2

Part 3

+1

Penso che uno svantaggio di Scala sarebbe l'incapacità di ridefinire la precedenza e l'associatività. Questi sono fissi (definiti dal primo e dall'ultimo carattere del nome del metodo). –

+0

Sì, questo ha un odore un po '. – skaffman

3

In C++ è possibile definire gli operatori che lavorano su altre classi, ma non credo che gli altri tipi primitivi come int che non possono avere metodi di istanza. È possibile creare la propria classe numerica in C++ e ridefinire TUTTI gli operatori, inclusi + * ecc.

Per creare nuovi operatori su tipi primitivi, è necessario passare alla programmazione funzionale (sembra dalle altre risposte). Va bene, tieni a mente che la programmazione funzionale è molto diversa da OOP. Ma sarà una grande nuova sfida e la programmazione funzionale è ottima per la matematica come viene da lambda calc. L'apprendimento della programmazione funzionale ti insegnerà diverse abilità e ti aiuterà molto con la matematica e la programmazione in generale. : D

buona fortuna!

2

Ada ha il supporto per superiori operatori infissi: qui è la reference manual chapter.

Purtroppo non è possibile creare i propri nuovi operatori, sembra che sia possibile ignorare solo quelli esistenti.

type wobble is new integer range 23..89; 

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

Ada non è un linguaggio estremamente popolare, deve essere detto, ma per quanto riguarda la tipizzazione forte va, non si può ottenere molto più forte.

EDIT:

Un'altra lingua che non è stato ancora citato è D. È anche un linguaggio fortemente tipizzato e supporta operator overloading. Ancora una volta, non supporta gli operatori di infisso definiti dall'utente.

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

Perché non consentire agli operatori definibili dall'utente?

Questi possono essere molto utili per allegare nuove operazioni di infisso a vari simboli Unicode. Il guaio è che in D, i token dovrebbero essere completamente indipendenti dall'analisi semantica. Gli operatori definibili dall'utente lo infrangerebbero.

2

Nella misura in cui la procedura applicata agli argomenti in una combinazione Lisp è denominata "operatore", allora sì, è possibile definire nuovi operatori fino a quando le mucche tornano a casa.

1

Penso che dovresti probabilmente riflettere profondamente sul motivo per cui desideri utilizzare questa funzione. Mi sembra che ci siano considerazioni molto più importanti nella scelta di una lingua.

Posso solo pensare a un possibile significato per la parola "operatore" in questo contesto, che è solo zucchero sintattico per una chiamata di funzione, ad es. foo + bar verrebbe tradotto come una chiamata a una funzione +(a, b).

Questo è talvolta utile, ma non spesso. Posso pensare a pochissimi casi in cui ho sovraccaricato/definito un operatore.

Come indicato nelle altre risposte, Haskell consente di definire nuovi operatori di infisso. Tuttavia, un linguaggio puramente funzionale con valutazione pigra può essere un po 'un boccone. Probabilmente raccomanderei SML su Haskell, se hai voglia di provare un linguaggio funzionale per la prima volta. Il sistema dei tipi è un po 'più semplice, puoi usare gli effetti collaterali e non è pigro.

F # è anche molto interessante e dispone anche di units of measure, che AFAIK è univoco per quella lingua. Se hai bisogno di funzionalità, può essere inestimabile.

Fuori dalla mia testa Non riesco a pensare a nessun linguaggio imperativo staticamente tipizzato con gli operatori infissi, ma potresti comunque voler usare un linguaggio funzionale per la programmazione matematica, dal momento che è molto più facile dimostrare fatti su un funzionale programma.

Si potrebbe anche voler creare un piccolo DSL se i problemi di sintassi come gli operatori infissi sono così importanti per voi. Quindi puoi scrivere il programma in qualsiasi lingua tu voglia e comunque specificare la matematica in un modo conveniente.

+0

La libreria boost C++ "Units" fornisce un'analisi dimensionale in fase di compilazione simile alle unità di misura F #. –

2

Entrambi gli ocaml e f# dispongono di operatori infissi. Hanno una serie speciale di caratteri consentiti all'interno della loro sintassi, ma entrambi possono essere utilizzati per manipolare altri simboli per utilizzare qualsiasi funzione infissa (vedere ocaml discussion).

0

È possibile eseguire effettivamente ciò che è necessario con C# tramite il sovraccarico dell'operatore.

Esempio:

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

+0

Sì, è vero, ma non puoi definire nuovi operatori, così sei limitato a +, -, *, /, gli operatori di confronto e altri ancora. Ma cosa succede se hai due set e vuoi ottenere l'unione dei due? Dovresti davvero andare e definire una funzione statica set.union (setA, setB)? – niklasfi

1

Che cosa si intende per tipizzazione forte? Intendi digitazione statica (in cui tutto ha un tipo noto al momento della compilazione e le conversioni sono limitate) o una digitazione forte (tutto ha un tipo noto in fase di esecuzione e le conversioni sono limitate)?

Vorrei andare con Common Lisp. In realtà non ha operatori (ad esempio, l'aggiunta di aeb è (+ a b)), ma piuttosto funzioni, che possono essere definite liberamente. Ha una forte digitazione in quanto ogni oggetto ha un tipo definito, anche se non può essere conosciuto in fase di compilazione e le conversioni sono limitate. È un vero e proprio linguaggio per la programmazione esplorativa, e sembra che sia quello che farai.

1

Ruby does.

require 'rubygems' 
require 'superators' 

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

["jay"] <--- "spillihp" 
Problemi correlati