2009-08-21 12 views
23

Quando si scrive il seguente oggi in C#Esistono lingue che consentono le unità?

DateTime.Now.AddYears(-60) 

mi chiedevo se ci sono lingue che permettono una sintassi più naturale con le unità:

DateTime.Now - 60years 

Qualcuno sa di qualsiasi? Nello specifico, sono interessato alla presenza di operatori di unità (?) Che trasformano "60 anni" in ad es. "TimeSpan.FromYears (60)". Sarebbe anche bello poter definire i propri operatori di unità, in modo simile a come è possibile scrivere operatori di conversione in C#

(Sì, so che TimeSpan non soddisfa per anni - è un esempio.)

+4

Sarebbe davvero utile per la NASA, quindi possono tranquillamente aggiungere metri e piedi. – MSalters

+0

O sicuro che metri e piedi non si mescolano intrinsecamente. –

+1

C++ 11 supporta letterali definiti dall'utente, che servono per implementare le unità. – pmr

risposta

22
+1

Se sto leggendo quel post, a) è fantastico ... b) F # deve implementare il proprio 'float' digita quindi, separato da 'System.Float'? In tal caso, possiamo utilizzare questo sistema da un altro linguaggio .NET con alcuni elementi sintattici? –

+0

a) F # utilizza lo standard .Net Float e Double, ma aggiunge il proprio tipo di inferenza e verifica di tipo. b) c'è un buon compromesso tra F # e altre lingue .Net –

+4

+1 per il codice suicida – Epaga

1

ho gues C++, è possibile effettuare la classe di quote con gli operatori di overload e alcune macro #define

+1

Ad esempio, utilizzando Unità boost: http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units.html –

-1

In Perl, è possibile utilizzare DateTime che permette cose come:

my $dt = DateTime->now 
$dt->subtract(hours => 1); 
0

non ho visto un tale linguaggio che lo supporta intrinsecamente. Comunque potresti certamente scrivere i tuoi oggetti basati sulla data in una varietà di lingue, se sei così incline.

2

La libreria Java JODA funziona in questo modo.

E c'è il JSR-275 che propone un quadro di unità.

Ho sentito parlare di questo problema nel 1997 da Martin Fowler. Ha scritto su di esso nel suo "Analysis Patterns".

+0

L'OP non si riferisce al supporto della lingua per la notazione delle unità, piuttosto che al supporto dell'API per concetto di unità? – skaffman

+0

Certo, ma non ne conoscevo uno. Perfino FORTRAN, il non plus ultra dei linguaggi informatici scientifici, non supportava le unità quando l'ho usato per l'ultima volta. – duffymo

10

Bene biblioteca ActiveSupport per Ruby estende la classe Integer con metodi come ore e giorni, che permette di scrivere le cose come:

Time.now + 5.days 

Ma che non è proprio una caratteristica della sintassi - è solo una chiamata di metodo ed è possibile in qualsiasi lingua che consente di aggiungere metodi a una classe esistente. Potresti farlo in C# con i metodi di estensione, anche se dovrebbe essere 5.days() lì.

+2

o proprietà di estensione -> 5.days. Altrimenti, si romperà quasi ogni "buon consiglio di programmazione" di cui sono a conoscenza. – nothrow

+0

Sì, i metodi di estensione sono un modo per farlo in .NET, convertendo 5.Days() in TimeSpan.FromDays (5). – bruceboughton

1

Non so se ne esiste ancora uno, ma mi aspetterei di iniziare a vedere queste cose spuntare come DSL s nel prossimo paio di anni. Sto pensando un po 'come una nuova generazione MATLAB o qualcosa del genere. Sono sicuro che ci sono un sacco di usi matematici, scientifici e ingegneristici per queste cose.

+0

wolframalpha.com lo fa – DmitryK

0

Sono sicuro che non è quello che stai cercando, ma nel settore delle apparecchiature di test e misura, non sarebbe inusuale per un 'programma di test' includere istruzioni che operano su valori espressi in tensione, corrente o unità di tempo.

Cose molto specializzate, tuttavia, e difficilmente riconoscibili dalla maggior parte come linguaggi di programmazione.

7

C'è una libreria Boost C++ per le unità che fa ampio uso della metaprogrammazione del modello per fornire qualcosa di simile alla sintassi che si desidera.

quantity<force>  F(2.0*newton); 
quantity<length> dx(2.0*meter); 
quantity<energy> E(work(F,dx)); 

http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units.html

+0

E con C++ 0x possiamo dire 'auto Table = 2.0 * meter * 3.0 * meter;'. – MSalters

0

funzione di PHP strtotime() lo fa molto bene.Prende una stringa e un tempo opzionale come parametri e analizzerà la stringa per capire una nuova ora.

Esempi:

$newTime = strtotime('last monday'); 
$newTime = strtotime('- 2 days', $originalTime); 
$newTime = strtotime('- 60 years', $originalTime); 
$newTime = strtotime('+ 1 week 1 day', $originalTime); 

più qui: http://us2.php.net/strtotime

+0

L'analisi delle stringhe non conta come una funzione di sintassi del linguaggio di programmazione !! – bruceboughton

2

Quando si utilizza le unità, si sta effettivamente l'assegnazione di un tipo. Le conversioni potrebbero essere implementate tramite casting o tramite chiamate di funzioni di differenziazione basate su tipi di parametri (overloading di funzioni). Quasi qualsiasi linguaggio tipizzato staticamente (che consente di definire a fondo i tipi) ti consentirebbe di fare qualcosa di simile. Ciò renderebbe il tuo programma più robusto, sebbene coloro che preferiscono linguaggi tipizzati dinamicamente potrebbero sostenere che i guadagni sono piccoli rispetto al tempo impiegato per implementare un sistema di tipo così completo per la maggior parte delle applicazioni. Costruire un Mars Climate Orbiter, d'altra parte, dovrebbe meritare un tale sistema di tipi.

La sintassi è un po 'diversa, ma il tuo esempio mi sembra molto simile agli esempi comuni di come alcuni userebbero il sistema di tipi di Haskell (o quello di qualsiasi linguaggio funzionale digitato), anche se, come ho detto, anche questo è fattibile anche in lingue simili a C.

1

SQL, o almeno MySQL ha un supporto di base basato sull'orario di base.

mysql> SELECT DATE_SUB(NOW(), INTERVAL 1 DAY) AS `yesterday`, NOW() + INTERVAL 1 DAY AS `tomorrow`; 
+---------------------+---------------------+ 
| yesterday   | tomorrow   | 
+---------------------+---------------------+ 
| 2009-08-20 06:55:05 | 2009-08-22 06:55:05 | 
+---------------------+---------------------+ 
1 row in set (0.00 sec) 
+0

È ancora meglio :) – vava

1

MySQL ha this feature


mysql> SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND; 
     -> '2009-01-01 00:00:00' 
mysql> SELECT INTERVAL 1 DAY + '2008-12-31'; 
     -> '2009-01-01' 
mysql> SELECT '2005-01-01' - INTERVAL 1 SECOND; 
     -> '2004-12-31 23:59:59' 
0

Non fa parte del linguaggio, ma ho visto che fatto prima in C, qualcosa come:

#define NOW  time(0) 
#define PLUS + 
#define AND  + 
#define MINUS - 
#define SECOND * 1 
#define SECONDS * 1 
#define MINUTE * 60 
#define MINUTES * 60 
#define HOUR * 3600 
#define HOURS * 3600 
#define DAY  * 86400 
#define DAYS * 86400 

time_t waitUntil = NOW PLUS 1 HOUR AND 23 MINUTES; 

Sembrava un abominio per me in quel momento, nella stessa classe come "#define begin {" e "#define end }" - se non ti piace il modo in cui la lingua funziona, usa una lingua diversa; non cercare di piegarlo alla tua volontà in un modo così orribile.

Sembra ancora un abominio, ma mi sono ammorbidito nella mia vecchiaia e posso almeno capire perché forse qualcuno ha pensato che fosse una buona idea.

+0

#define MINUTE * 36? – Dave

+0

Grazie, @Dave, errore di battitura da parte mia. – paxdiablo

+0

Se hai buttato via le prime 4 #definite e hai usato la matematica corretta, non sarebbe male C. –

0

PowerShell ha qualche supporto di base.Ad esempio, 5GB/1MB valuta a 5120

4

La nuova lingua di Sun Fortress supporta le unità e, se la memoria serve, è abbastanza intelligente da impedirti di fare cose strane come sottrarre misure di tempo da misure di lunghezza.

E Mathematica ha unità di misura e una sintassi non troppo complessa per gestirle.

+0

Voi ragazzi può vedere ciò che la sintassi si presenta come qui: http://research.sun.com/projects/plrg/PLDITutorialSlides9Jun2006.pdf Pagina 17/124 – sivabudh

3

Unum praticamente fa esattamente questo per Python, permettendo il codice come:

>>> TON + 500*KG 

1.5 [t] 

>>> 5E-8*M - 28*ANGSTROM 

472.0 [angstrom] 

>>> 3*H + 20*MIN + 15*S 

3.3375 [h] 

>>> H == 60*MIN 

True 

>>> 10000*S > 3*H + 15*MIN 

False 

>>> 
0

Syntacticly, io non sono davvero sicuro di quello che il benifit sarebbe di

DateTime.Now + 60 years 

corso

DateTime.Now.AddYears (60) 

Il mio metodo tipico per gestire "unità" è definire costanti che convertono quelle unità nell'unità di base dell'oggetto dati se moltiplicate. Dal momento che qualcuno (breifly) tagged questo con Ada, la versione Ada sarebbe:

Years : constant := 60.0 * 60.0 * 24.0 * 365.0; 
DateTime.Now := DateTime.Now + (60.0 * Years); 

penso che si può fare più o meno lo stesso pensare in C++, se non che i loro oggetti di tempo sono suscettibili di essere grandi numeri interi, invece di reali .

+0

Non stavo chiedendo di necessità di tale sintassi, più per curiosità. Sicuramente per il mio esempio, la sintassi dell'unità non offre davvero molto. – bruceboughton

2

Non unità, di per sé ... ma un modo per utilizzare i metodi di estensione per fornire funzionalità unitarie. Questo esempio è specifico per TimeSpan.

static class TimeExtensions 
{ 
    public static TimeSpan ToDays(this int i) 
    { 
     return new TimeSpan(i, 0, 0, 0, 0); 
    } 

    public static TimeSpan ToHours(this int i) 
    { 
     return new TimeSpan(0, i, 0, 0, 0); 
    } 

    public static TimeSpan ToMinutes(this int i) 
    { 
     return new TimeSpan(0, 0, i, 0, 0); 
    } 

    public static TimeSpan ToSeconds(this int i) 
    { 
     return new TimeSpan(0, 0, 0, i, 0); 
    } 

    public static TimeSpan ToMilliseconds(this int i) 
    { 
     return new TimeSpan(0, 0, 0, 0, i); 
    } 
} 

Quindi, semplicemente 4.ToMinutes() fornisce un TimeSpan di 4 minuti. Se si dispone di classi di base simili con cui lavorare per rappresentare altri tipi di unità, è possibile aggiungere lo stesso tipo di funzionalità di estensione.

. (Nota: questo è solo una rappresentazione C# dell'esempio Ruby)

1

io so cosa vuoi dire, e anch'io sono stato curioso di questo. (Il mio insegnante di chimica del liceo era convinto che i numeri senza unità fossero abbastanza privi di significato.)

Con qualsiasi linguaggio fortemente tipizzato, è possibile scrivere classi per questi concetti. Li ho scritti in C++, Java e Pascal. Google "Unità" e "Java" e puoi trovare una libreria che ha incapsulati tutti i tipi di misurazioni fisiche come questa.

C++, con le sue conversioni di tipo slicker e il sovraccarico dell'operatore può rendere questo aspetto più naturale. In realtà puoi rendere le cose piuttosto fluide, ottenere ciò che penso che vuoi. Java, sebbene lo faccia, richiederà conversioni più esplicite e una sintassi scomoda.

Ma no, non l'ho visto.

Cerca linguaggi specifici di dominio creati per gli scienziati, anche quelli "educativi".

1

Frink è un linguaggio appositamente creato per "calcoli fisici" come quello. Dalla documentazione:

Frink è uno strumento di calcolo e linguaggio di programmazione pratico progettato per fare calcoli fisici semplice, per contribuire a garantire che le risposte vengono fuori destra [..].Tiene traccia di unità di misura (piedi, metri, chilogrammi, watt, etc.) attraverso tutti i calcoli, che consente di mescolare unità di misura in modo trasparente [..]

vostro esempio in Frink:

now[] - 60 years 
2

Ada e suo cugino, VHDL, supportano direttamente il concetto di unità. Dal momento che queste lingue sono estremamente tipizzate, le unità sono un'abilità naturale della severità dei tipi.

Problemi correlati