Perché non esiste un tipo di "numero complesso" primitivo in Java?

3

Qualcuno sa perché qualcosa come libreria cj per numeri complessi non è mai stato completato e integrato in Java principale?

Questo mi sembra un gioco da ragazzi ... Mi rendo conto che le gawds di Java non vogliono trasformare Java in C ++ ma questa è una cosa che C ++ gestisce splendidamente e l'implementazione di questo ragazzo (scritta 17 anni fa!) gestisce in modo eccellente ma è ormai irrimediabilmente obsoleto per essere di uso pratico.

Sì. Aggiungi anche quaternioni e octonioni. Ma questo è tutto. Non sto suggerendo una scatola di Pandora. I numeri reali, complessi, quaternionici e octonionici sono le uniche algebre a divisione normale. Si potrebbe controbattere tuttavia, rimanendo nel regno di * essere sempre commutativi per quanto riguarda l'ordine delle operazioni. Torna indietro e leggi l'articolo a cui mi sono collegato nell'OP. Generare milioni di oggetti temporanei per spammare il GC è dispendioso e rende Java appropriato per alcune attività che potrebbero essere facilmente rese idonee. La cosa che distingue un primitivo è che è un'unità, e non un puntatore a un mucchio. Se vai all'estremo OO, potresti anche unirti al campo che dice che anche le doppie primitive dovrebbero essere eliminate. Sì, quello che sto suggerendo equivale a un operatore integrato che compila codici byte completi standard e mappe di una coppia di doppi. Vedere l'implementazione cj e README I collegati. Un sovraccarico dell'operatore in piena regola sarebbe un disastro, ma questo è facilmente fattibile.

Non sto suggerendo solo l'estensione della lingua a tipi complessi.

Per le mie idee, vedi l'articolo che ho scritto riassumendo questo libro su Clifford Algebras

link

Per esempio, i tipi di dati complessi sono fondamentali per l'informatica quantistica .. ma anche, il commento qui sotto sui tipi definiti dall'utente, benché accurato, non si presta a unire insieme un codice complesso ad alte prestazioni (no pun intended) che può essere filato al volo dal jvm o da qualsiasi hardware, quantico, classico o altro ... già pensando a questo qui .. e no, non è una proliferazione di incasinare "java purezza" ma è in realtà il rigoroso, scientifico ecc. es BUONO, modo di fare le cose ... apre possibilità a chi può usarle.

Ad esempio, questi costrutti (no non l'ho appena estratto dal nulla, ma quasi così ..) suonano come la soluzione perfetta per alcune applicazioni alla teoria del compilatore e ai torni e input / output dell'utente (modellati come osservabili come output e processi stocastici come input).

1.2.3. Exact Sequences, Centers, and Centralizers. A group G is simple if it has no normal subgroups other than {e} and G. The group with one element is denoted by 1 if the composition law is multiplication, or 0 if the composition law is addition. Suppose that a sequence of groups {G0 = 1, G1, , Gk, Gk+1 = 1} is given and that θj: Gj → Gj+1 is a morphism for ...then the diagram...is an exact sequence if θj−1(Gj−1) is the kernel of θj∀1 6 j 6 k. When k = 3 the sequence is a short exact sequence. }

    
posta crow 04.04.2016 - 22:25
fonte

4 risposte

13

In generale, è un brutto segno se devi cambiare la lingua per aggiungere un nuovo tipo di dati o un'operazione. Ciò significa che alla lingua mancano alcune funzionalità che ti impediscono di esprimere il tuo programma.

Stai proponendo di cambiare la lingua e aggiungere un tipo complex . Come @Thomas Eding accennato sopra: perché fermarsi qui? E i quaternioni? Sorgono abbastanza frequentemente in fisica quantistica e grafica 3D. Probabilmente sono anche più utili dei numeri complessi. E i numeri razionali? Numeri reali (non in virgola mobile)? Numeri naturali? Numeri interi (non int modulo 2 32 , ma reali numeri interi arbitrari)?

No. Non è possibile continuare ad accumulare funzionalità in cima alle funzionalità. La lingua si sgretolerà sotto il suo stesso peso.

La funzione che veramente ha bisogno è Tipi di valore . E tu cosa sai? Sono già in lavorazione e probabilmente appariranno in Java 11 al più tardi. I tipi di valore consentirebbero di implementare la semantica di complex come libreria. E la semantica di quaternioni, octonioni, grandi decimali, razionali, tuple, strutture, record, soldi, date, ... tutti senza che devono cambiare la lingua.

Lo ammetto, ti permetterebbe solo di implementare la semantica, comunque.

Per implementare la sintassi , avremmo bisogno di due funzionalità aggiuntive:

  • overloading dell'operatore (già esistente nella lingua, ma non definito dall'utente)
  • letterali definiti dall'utente (esistono in C ++, in Scala, in altre lingue)

L'overloading dell'operatore ti consentirebbe di scrivere c1 + c2 anziché c1.plus(c2) . I valori letterali definiti dall'utente consentono di scrivere 2i anziché new Complex(0, 2) . La combinazione di entrambi ti consentirebbe di scrivere 2 + 3i anziché new Complex(2, 3) .

Forse lo otterremo. Forse no. Scala ha dimostrato che l'overloading dell'operatore e gli operatori definiti dall'utente possono essere eseguiti con molto gusto e ha anche dimostrato che possono essere sfruttati e abusati. Guarda la DSL di SBT per un uso estremamente elegante e ben bilanciato del sovraccarico dell'operatore.

La cosa interessante di veramente è che se dovessimo ottenere tipi di valore, letterali definiti dall'utente e overloading dell'operatore, mentre ciò aggiungerebbe sicuramente complessità al linguaggio, ci permetterebbe allo stesso tempo rimuovere tutti gli 8 primitivi dalla lingua e implementarli come una libreria! Che a sua volta sarebbe semplificare la lingua.

Questo è un ottimo segno per una funzione della lingua buona : se aggiungerla effettivamente rende la lingua più piccola . Questo non è vero per la tua proposta, che è fondamentalmente quella di aggiungere un altro tipo specialistico one-off ai primitivi one-off specializzati già esistenti.

    
risposta data 05.04.2016 - 02:12
fonte
7

Tipi primitivi nei linguaggi di programmazione: tipi di CPU astratti, che sono scalari. I numeri complessi non sono scalari, sono tipi aggregati perché ci sono due numeri.

Come lo progetteresti? I numeri complessi sono spesso usati nei calcoli, e Java non gestisce questo bene.

Sarebbe generico, per consentire numeri di dimensioni diverse? Ora devi inserire i tipi primitivi perché Java non consente tipi generici primitivi. Ciò danneggerebbe le prestazioni, dato il caso d'uso per numeri complessi.

Sarebbe una classe che incapsula due primitivi, ad es. %codice%? Che cosa succede se hai bisogno di diversi tipi, forse class Complex { public double r, i;} o float ?

Non esiste un approccio di adattamento a taglia unica a causa della natura dei generici di Java. La libreria standard di Java è già piena di classi obsolete (ci sono almeno tre modi per caricare un'immagine e una di queste non funziona affatto). Perché aggiungere una classe che sappiamo già non funzionerà in un numero elevato di casi?

La soluzione corretta è lasciare il tipo non specificato e consentire alle persone che ne hanno bisogno di scriverne di proprie. Mi ci sono voluti tutti dieci secondi in quel piccolo esempio sopra. Questo ha il vantaggio che gli sviluppatori possono soppesare i compromessi e scriverlo in modo appropriato per le loro esigenze.

    
risposta data 04.04.2016 - 23:04
fonte
4

Le primitive built-in come char, int, boolean ecc. sono generiche e utili per quasi tutti i tipi di computer. I numeri complessi, d'altra parte, sono piuttosto specifici per il dominio e utilizzati principalmente nell'informatica scientifica. Non ci sono abbastanza utili da giustificare l'appartenenza al nucleo di primitivi. Si noti che Java è stato inizialmente progettato per essere più semplice di C ++ e il dominio di destinazione era costituito da dispositivi e appliance, non da calcolo scientifico.

Quindi perché i numeri complessi non sono supportati a livello di libreria? Il problema è che Java non supporta l'overloading dell'operatore, il che significa che qualsiasi tipo di calcolo che utilizza tipi numerici personalizzati sarà incredibilmente brutto. Invece di a + b * c dovrai scrivere qualcosa come Numeric.add(a, Numeric.multiply(b, c)) . Ma i progettisti di Java hanno deliberatamente scelto di escludere il supporto per il sovraccarico dell'operatore perché ritenevano che tendesse a condurre a un codice criptico. Così hanno sacrificato un dominio specifico (calcolo numerico) al fine di creare un linguaggio più genericamente produttivo.

Java semplicemente non è progettato per il calcolo numerico e scientifico e richiederebbe modifiche fondamentali per essere un contendente in questo spazio.

    
risposta data 05.04.2016 - 09:09
fonte
0

Perché il concetto di "numero complesso" è, per definizione, non un tipo primitivo . Si tratta di un raggruppamento di due numeri reali distinti, il primo dei quali è designato arbitrariamente come "il componente reale" e l'altro dei quali è designato come "il componente immaginario".

In altre parole, il concetto è perfettamente adatto al concetto di programmazione di una struct . (Che Java non ha, ma è un altro problema.)

    
risposta data 04.04.2016 - 22:58
fonte

Leggi altre domande sui tag