2009-08-21 6 views
23

Wenn die folgenden heute in C# zu schreibenGibt es Sprachen, die Einheiten erlauben?

DateTime.Now.AddYears(-60) 

Ich fragte mich, ob es irgendwelche Sprachen sind, die eine natürlichere Syntax mit Einheiten erlauben:

DateTime.Now - 60years 

Kennt jemand überhaupt? Insbesondere interessiert mich das Vorhandensein von Einheitsoperatoren (?), Die "60 Jahre" in z. "TimeSpan.FromYears (60)". Es wäre auch nett, in der Lage zu sein, Ihre eigenen Unit-Operatoren zu definieren, ähnlich wie Sie Conversion-Operatoren in C#

definieren können (Ja, ich weiß, dass TimeSpan nicht für Jahre sorgt - es ist ein Beispiel.)

+4

Wäre wirklich nützlich für die NASA, so dass sie Meter und Fuß sicher hinzufügen können. – MSalters

+0

Oder sicher fangen, dass Meter und Füße sich nicht von Natur aus vermischen. –

+1

C++ 11 unterstützt benutzerdefinierte Literale, die der Implementierung von Einheiten dienen. – pmr

Antwort

22
+1

Wenn ich diesen Post richtig lese, a) das ist genial ... b) F # muss seinen eigenen 'float' implementieren Geben Sie dann, getrennt von 'System.Float'? Wenn ja, können wir dieses System aus anderen .NET-Sprachen mit einigen syntaktischen Fehlern verwenden? –

+0

a) F # verwendet den Standard .Net Float und Double, fügt aber eigene Inferenz und Überprüfung hinzu. b) Es gibt eine gute Schnittstelle zwischen F # und anderen .Net-Sprachen –

+4

+1 für den selbstmörderischen Code – Epaga

1

I gues C++ können Sie Einheitenklasse mit überladenen Operatoren und einige #define Makros

+1

Zum Beispiel mit Boost Units: http://www.boost.org/doc/libs/1_37_0/doc/html/boost_units.html –

-1

In Perl, die Sie verwenden können DateTime machen, die solche Dinge wie erlaubt:

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

so habe ich nicht gesehen ein Sprache, die es von Natur aus unterstützt. Allerdings könnten Sie sicherlich Ihre eigenen datumsbasierten Objekte in einer Vielzahl von Sprachen schreiben, wenn Sie so geneigt sind.

2

Javas JODA Bibliothek funktioniert so.

Und es gibt JSR-275, die ein Einheiten-Framework vorschlagen.

Ich habe das erste Mal 1997 von Martin Fowler über dieses Problem gehört. Er schrieb darüber in seinem "Analysis Patterns".

+0

Nicht die OP bezieht sich auf Sprachunterstützung für Unit-Notation, anstatt API-Unterstützung für die Konzept der Einheiten? – skaffman

+0

Natürlich, aber ich wusste von keinem. Selbst FORTRAN, das Non-Plus-Ultra der wissenschaftlichen Computersprachen, unterstützte die Einheiten nicht, wenn ich sie zuletzt benutzte. – duffymo

10

Nun, die Active Bibliothek für Ruby erweitert die Integer-Klasse mit Methoden wie Stunden und Tagen, die Sie Dinge wie schreiben kann:

Time.now + 5.days 

Aber das ist nicht wirklich eine Syntax-Funktion - es ist nur ein Methodenaufruf und ist in jeder Sprache möglich, in der Sie einer vorhandenen Klasse Methoden hinzufügen können. Sie könnten es in C# mit Erweiterungsmethoden tun - obwohl es dort 5.days() sein müsste.

+2

oder Erweiterungseigenschaft -> 5.days. Es wird fast jeden 'guten Programmier-Rat' brechen, den ich kenne. – nothrow

+0

Ja, Erweiterungsmethoden sind eine Möglichkeit, dies in .NET zu tun, indem 5.Days() in TimeSpan.FromDays (5) konvertiert wird. – bruceboughton

1

Ich weiß nicht, ob es noch existiert, aber ich würde erwarten, dass solche Dinge in den nächsten paar Jahren als DSL s erscheinen. Ich denke so etwas wie eine nächste Generation MATLAB oder so. Ich bin mir sicher, dass es für solche Dinge viele mathematische, wissenschaftliche und technische Anwendungen gibt.

+0

wolframalpha.com macht das – DmitryK

0

Ich bin mir sicher, dass es nicht das ist, wonach Sie suchen, aber im Bereich der Prüf- und Messgeräte wäre es nicht ungewöhnlich, dass ein "Testprogramm" Anweisungen enthält, die mit Spannung und Strom arbeiten oder Zeiteinheiten.

Sehr spezialisierte Sachen, und kaum von den meisten als Programmiersprachen erkennbar.

7

Es gibt eine Boost C++ - Bibliothek für Units, die die Template-Metaprogrammierung weitgehend verwendet, um etwas zu liefern, das der von Ihnen gewünschten Syntax ähnelt.

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

Und mit C++ 0x können wir 'auto Table = 2.0 * Meter * 3.0 * Meter sagen;'. – MSalters

0

PHP strtotime() Funktion macht es sehr schön.Es nimmt eine Zeichenfolge und eine optionale Zeit als Parameter und analysiert die Zeichenfolge, um eine neue Zeit herauszufinden.

Beispiele:

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

hier Mehr: http://us2.php.net/strtotime

+0

String Parsing zählt nicht wirklich als Programmiersprache Syntax-Funktion! – bruceboughton

2

Wenn Sie Einheiten verwenden, die Sie zuweisen tatsächlich einen Typ. Die Konvertierungen könnten durch Casting oder durch Differenzieren von Funktionsaufrufen basierend auf Parametertypen (Funktionsüberladen) implementiert werden. Fast jede statisch typisierte Sprache (die es erlaubt, Typen genau zu definieren) würde Ihnen erlauben, etwas Ähnliches zu tun. Es würde Ihr Programm robuster machen, obwohl diejenigen, die dynamisch typisierte Sprachen bevorzugen, argumentieren könnten, dass die Gewinne im Vergleich zur Zeit, die für die meisten Anwendungen mit der Implementierung eines solchen gründlichen Typsystems verbracht wurde, gering sind. Andererseits würde ein Aufbau eines Mars Climate Orbiter solch ein Typsystem verdienen.
Die Syntax ist ein wenig anders, aber Ihr Beispiel scheint mir sehr ähnlich zu üblichen Beispielen, wie einige würden Haskell-Typ-System (oder das von jeder typisierten funktionalen Sprache) verwenden, obwohl, wie ich bereits erwähnt, dies auch machbar ist in C-ähnlichen Sprachen.

1

SQL, oder zumindest MySQL hat einige grundlegende zeitbasierte Unterstützung.

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

Es ist sogar besser als das :) – vava

1

MySQL hat 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' 
2

die Antwort finden Sie auf C# Extensions wo der int-Klasse erweitert Methoden wie Stunden zu unterstützen(), Tage() usw.

Powershell hat die kB, MB, and GB operators für die Handhabung von Dateigrößen usw.

Die DATE_ADD() function in MSSQL akzeptiert Einheiten wie Tag, Stunde usw. für Datumsarithmetik.

0

nicht Teil der Sprache, aber ich habe das vor in C, so etwas wie getan gesehen: zu der Zeit, in der gleichen Klasse wie "#define begin {" und "#define end }"

#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; 

Es schien mir einen Greuel - Wenn Ihnen die Funktionsweise der Sprache nicht gefällt, verwenden Sie eine andere Sprache. Versuche nicht, es so scheußlich deinem Willen zu beugen.

Es scheint immer noch wie ein Greuel, aber ich bin in meinem Alter gemildert und kann zumindest verstehen, warum vielleicht jemand dachte, es wäre eine gute Idee.

+0

#define MINUTE * 36? – Dave

+0

Danke, @Dave, Tippfehler meinerseits. – paxdiablo

+0

Wenn du die ersten 4 #defines rausgeworfen hast und richtig berechnet hast, wäre es nicht schlecht C. –

0

Powershell hat einige grundlegende Unterstützung.Zum Beispiel 5GB/1MB ausgewertet 5120

4

Suns neue Sprache Fortress unterstützt Einheiten und, wenn der Speicher dient, ist intelligent genug, um Sie zu tun seltsame Dinge wie Subtrahieren Maßnahmen der Zeit von Längenmaß zu stoppen.

Und Mathematica hat Maßeinheiten und eine nicht zu sperrige Syntax für die Handhabung.

+0

Ihr könnt sehen, was die Syntax sieht aus wie hier: http://research.sun.com/projects/plrg/PLDITutorialSlides9Jun2006.pdf Seite 17/124 – sivabudh

3

Unum tut so ziemlich genau das für Python, so dass Code wie:

>>> 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

syntaktisch, ich bin nicht wirklich sicher, was die benifit von

DateTime.Now + 60 years 

über

DateTime.Now.AddYears (60) 
wäre

Meine typische Methode für den Umgang mit "Einheiten" ist die Definition von Konstanten, die diese konvertieren Einheiten in die Basiseinheit des Datenobjekts, wenn sie multipliziert werden. Da jemand (breifly) diese mit Ada markiert, würde die Ada-Version sein:

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

ich glaube, Sie recht machen kann viel das gleiche in C denken ++, mit der Ausnahme, dass ihre Zeit Objekte haften großen ganzen Zahlen statt reellen Zahlen sein .

+0

Ich war nicht für eine solche Syntax aus Not zu fragen, mehr aus Neugier. Für mein Beispiel bietet die Einheitensyntax nicht wirklich viel. – bruceboughton

2

Keine Einheiten, per se ... aber eine Möglichkeit, Erweiterungsmethoden zu verwenden, um Einheitsfunktionen zu erhalten. Dieses Beispiel gilt speziell für 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); 
    } 
} 

Dann einfach 4.ToMinutes() gibt Ihnen eine TimeSpan von 4 Minuten. Wenn Sie ähnliche Basisklassen haben, mit denen Sie arbeiten können, um andere Einheitentypen darzustellen, können Sie die gleiche Art von Erweiterungsfunktionalität hinzufügen.

. (Anmerkung: dies ist lediglich eine C# Darstellung des Ruby-Beispiel)

1

weiß ich, was Sie meinen, und ich habe auch schon darüber neugierig. (Meine High-School-Chemielehrerin bestand darauf, dass Zahlen ohne Einheiten ziemlich bedeutungslos waren. Wie auch immer ...)

Mit jeder stark typisierten Sprache können Sie Klassen für diese Konzepte schreiben. Ich habe sie in C++, Java und Pascal geschrieben. Google "Units" und "Java" und Sie können eine Bibliothek finden, die alle Arten von physikalischen Messungen wie diese gekapselt hat.

C++, mit seinen schlanken Konvertierungen und Überlastung des Operators kann dies natürlicher aussehen. Du kannst die Dinge ziemlich glatt machen, indem du das bekommst, was ich denke, dass du willst. Java erfordert, obwohl es dies tut, explizitere Konvertierungen und unbeholfene Syntax.

Aber nein, ich habe es nicht gesehen.

Suchen Sie nach domänenspezifischen Sprachen, die für Wissenschaftler erstellt wurden, sogar "Bildungs" -Sprachen.

1

Frink ist eine Sprache, die speziell für "physikalische Berechnungen" entwickelt wurde. Aus der Dokumentation:

Frink ist eine praktische Rechenwerkzeug und Programmiersprache entwickelt, um physikalische Berechnungen einfach zu machen, zu Hilfe sicherzustellen, dass Antworten kommen aus rechts [..].Es verfolgt Maßeinheiten (Fuß, Meter, Kilogramm, Watt, etc.) durch alle Berechnungen, Sie ermöglicht Maßeinheiten zu mischen transparent [..]

Ihr Beispiel in Frink:

now[] - 60 years 
2

Ada und seine Cousine, VHDL, unterstützen direkt das Konzept der Einheiten. Da diese Sprachen extrem stark typisiert sind, sind Einheiten eine natürliche Fähigkeit der Strenge von Typen.

Verwandte Themen