Język programowania D - nowa nadzieja czy niewypał

Odpowiedz Nowy wątek
2011-09-25 08:46
0

Język programowania D jest statycznie typowanym, kompilowanym językiem wieloparadygmatowym. Pierwsza stabilna wersja pojawiła się w 2007 roku i od tego czasu struktura języka dość mocno ewoluowała. Najważniejsze cechy języka wyróżniające go głównie od C++:

  • prawdziwe moduły, nie ma podziału na nagłówki oraz pliki z implementacją, jednak istnieje możliwość zawarcia interface'u w osobnym pliku
  • brak wielodziedziczenia, zamiast tego mamy interface'y
  • statyczne ify, które są rozwijane w czasie kompilacji
  • samodzielne szablony, co w sumie pozwala na łatwe metaprogramowanie
    template Factorial(ulong n) {
    static if(n <= 1)
        const Factorial = 1; // można zauważyć, że jeśli typ jest określony jako const to jest on określany na podstawie przypisanej wartości
    else
        const Factorial = n * Factorial!(n - 1);
    }
  • szablony są określane poprzez !() co pozwala uniknąć problemów jakie są w C++ np. z X< 1>2 > x1. Jednak jeśli mamy tylko pojedynczy argument szablonu można to zapisać jako X!my_func x
  • ujednolicony zapis typów w postaci <typ> <nazwa> oraz brak wielowyrazowych typów jak unsigned int, zamiast tego mamy uint, np.
    uint[] tab; // tablica liczb bez znaku
    real pi = 3.14; // liczba typu rzeczywistego
    MyClass my_instance; // nie tworzy jeszcze instancji, by ją stworzyć trzeba użyć new MyClass();
    my_instance = new MyClass();
    string str = "abba"; // string jest aliasem do immutable(char)[] przez co sama tablica jest zmienna, ale nie da się zmieniać poszczególnych znaków
    char[] editable_str = str.dup; // edytowalna kopia
    const E =2.7182818; // automatyczne określenie typu jako real
    idouble imaginary_number = 7.4i; // wbudowane liczby urojone i zespolone
    creal complex_number = 15.3 + 3.992i + imaginary_number;
  • silny podział na klasy i struktury
  • wbudowany Garbage Collector
  • możliwość leniwej ewaluacji argumentów, np.
    
    void my_func(int i, lazy void x) {
    while(--i)
        x();
    }

int x = 0;
my_func(3, writeln(x++));

* wbudowane w rdzeń języka tablice asocjacyjne oraz wektory
```d
int[string][] table;
table["abba"] = [ 1, 3, 6, 28, 46 ];
table["baba"] = [ 5, 8, 2849, 53 ];
table["abba"] ~= [ 2, 5, 7 ]; // operator ~ służy do konkatenacji tablic
  • programowanie kontraktowe.
    pure int f(int x)
    in {
    // sprawdzenie argumentów na wejściu
    }
    out {
    // sprawdzenie wyjścia
    }
    body {
    // ciało funkcji
    }
  • unit testy zawarte w bloku unittest {}

Co sądzicie o tym wynalazku?


edytowany 1x, ostatnio: hauleth, 2011-09-25 12:50
*ewoluowała - Wibowit 2011-09-25 12:33

Pozostało 580 znaków

2011-09-25 13:18
0

A szybsze to niż przynajmniej najnowsze JVMy?

Moim zdaniem prym wiodą języki zarządzane i nie ma się co temu dziwić. C/ C++/ Pascal/ itp są używane generalnie dlatego, aby:

  1. wyciągnąć te kilkadziesiąt procent więcej wydajności,
  2. być w pełni zgodnym z natywnymi API, tzn np w przypadku Javy nie da się wysłać normalnej tablicy po JNI bez narzutu spowodowanego wstrzymaniem GC albo przekopiowaniem tablicy do natywnego bufora,
  3. zredukować zajętość pamięci - konsole dla przykładu mają bardzo mało pamięci, więc tam pakowanie JVMa nie miałoby sensu,

brak wielodziedziczenia, zamiast tego mamy interface'y

Ależ teraz jest parcie na to jednodziedziczenie. Moim zdaniem wielodziedziczenie jest OK, o ile nie wielodziedziczymy stanu, a tylko implementacje metod. Dla przykładu w C# mamy Extension Methods (chyba dobrze napisałem), a w Javie 8 mają być Defender Methods (czyli coś a la Extension Methods, tylko można tam dziedziczyć implementacje, więc jest to rozwiązanie bardziej skalowalne).

Moim zdaniem wielodziedziczenie stanu w C++ to jedna skrajność, a zupełny brak wielodziedziczenia to druga skrajność.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2011-09-25 13:25
0

A co z przeciążaniem i definiowaniem operatorów?

Wibowit napisał(a)

Moim zdaniem wielodziedziczenie jest OK, o ile nie wielodziedziczymy stanu, a tylko implementacje metod.

Moim zdaniem implementacje metod lepiej delegować.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
edytowany 1x, ostatnio: somekind, 2011-09-25 13:28
Do czyjego postu się odnosisz? - Wibowit 2011-09-25 13:29

Pozostało 580 znaków

2011-09-25 14:03
0

Moim zdaniem implementacje metod lepiej delegować.

A to niby dlaczego? Delegowanie to dokładanie niepotrzebnego śmiecia do kodu, tak samo jak rozwlekłe gettery i settery w Javie. Zwłasza jeśli implementacje metod są krótkie, np na jedną linijkę (w jednej linijce w np Scali można naprawdę dużo zrobić).

Myślę sobie o języku w którym można by zrobić dynamiczne wstrzykiwanie implementacji (tzn w locie, nie na etapie kompilacji), coś na wzór:

SynchronizedSet synchronizedSetObject = nonSynchronizedSetObject with SetSynchronizationSupport

Obecnie można by coś takiego zasymulować właśnie za pomocą delegacji, ale wymaga to sporego nadmiarowego kodu jeśli symulujemy jednocześnie wielodziedziczenie.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 2x, ostatnio: Wibowit, 2011-09-25 14:03

Pozostało 580 znaków

2011-09-25 14:15
0

Delegowanie, mimo dokładania kodu, daje dużo większą elastyczność niż dziedziczenie.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2011-09-25 14:21
0

Ta elastyczność jest w małym stopniu wykorzystywana, a powoduje znaczne pogorszenie czytelności. Wg mnie elastyczność kosztem czytelności to zła droga.

Poza tym dynamiczne wstrzykiwanie implementacji nie byłoby praktycznie ani trochę mniej elastyczne niż delegowanie kodu.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2011-09-25 14:24

Pozostało 580 znaków

2011-09-25 17:33
0

Aaaaaa, zapomniałem. Zamiast wielodziedziczenia możemy mieć mixiny szablonów. Czyli dajmy na to:

template MyMixin() {
    void hello(string name) {
        writeln("Hello ", name, "!");
    }
}

class MyClass {
    mixin MyMixin!();
}
// ...
MyClass c = new MyClass();
c.hello();

Co daje efekt podobny do prywatnego dziedziczenia z C++.

Definiować własnych operatorów nie idzie, ale przeciążanie działa w ten sposób, że mamy funkcję opUnary oraz opBinary i one przechwytują wywołania operatorów:

class MyClass {
    MyClass opUnary(string op)()
    if (op == "!") {
        // implementacja operatora !
    }

    MyClass opBinary(string op)(MyClass c)
    if (op == "~") {
        // implementacja konkatenacji
    }

    int opCmp(MyClass c) {
        // operator porównania, zwraca -1 jeśli większe, 0 jeśli równe i 1 jeśli mniejsze
        // pozwala to na przeładowanie wszystkich 6 operatorów (==, <, >, !=, <=, >=) za jednym zamachem
    }
}

Oprócz tego delegaty i wskaźniki na funkcje mają wręcz debilnie proste typy (w przeciwieństwie do C++)

int function(int) my_func; // odpowiednik C++ int (*my_func)(int);
int delegate(int) my_delegate;

edytowany 1x, ostatnio: hauleth, 2011-09-25 22:43

Pozostało 580 znaków

2011-09-25 23:40
0

Te mixiny to po prostu moim zdaniem wielodziedziczenie (i to na sterydach bym powiedział), z tym, że przy niejednoznacznościach kod się po prostu nie kompiluje, tzn nie ma mechanizmu obsługiwania niejednoznaczności. A więc nie jest to wielodziedziczenie w ścisłym (tzn Wikipediowym) tego słowa znaczeniu.

W sumie zależy co rozumieć przez wielodziedziczenie. Powinni zrobić jakieś rozróżnienie pomiędzy wielodziedziczeniem, a "wieloimplementacjami", tzn między sytuacją kiedy niejednoznaczności są niedozwolone, a kiedy są. Defender methods z Javy 8 nie wprowadzą w takim razie do Javy wielodziedziczenia w ścisłym tego słowa znaczeniu, ani Extension Methods z C# też nie wprowadzają.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2011-09-25 23:41

Pozostało 580 znaków

2011-09-26 23:35
0
Wibowit napisał(a)

Ta elastyczność jest w małym stopniu wykorzystywana, a powoduje znaczne pogorszenie czytelności. Wg mnie elastyczność kosztem czytelności to zła droga.

W małym stopniu? Delegowanie zwiększa elastyczność i testowalność aplikacji za to zmniejsza błędogenność zmian w kodzie. Praktyczne programowanie obiektowe polega na delegowaniu i komponowaniu, a nie na dziedziczeniu. Nie widzę możliwości napisania przydatnego kodu opartego na dziedziczeniu zamiast delegacji.

Poza tym dynamiczne wstrzykiwanie implementacji nie byłoby praktycznie ani trochę mniej elastyczne niż delegowanie kodu.

Jeśli kod jest napisany obiektowo, tzn. oparty na interfejsach, a nie implementacjach, to nie ma raczej z tym problemu.

winerfresh napisał(a)

Definiować własnych operatorów nie idzie

No to trochę słabo.
A jak z wydajnością?


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2011-09-26 23:46
0

trait Ordered

Możliwość zmiksowania tego traitu do dowolnej klasy jest moim zdaniem bardzo wygodna. Na pewno tworzenie delegatów tutaj nie ma najmniejszego sensu.

Generalnie takie twoje gadanie jest identyczne z gadaniem twórców Javy i jej pierwszymi piewcami. Twierdzili oni, że za pomocą interfejsów da się elegancko załatwić wszystko co tylko możliwe. Tyle, że teraz nawet sam ojciec Javy chwali Scalę, która przecież ma wielodziedziczenie. Poza tym programowanie obiektowe nie wymusza pojedynczego dziedziczenia.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2011-09-27 14:43
0

Język D w wersji 2.0 pozwala na przeciążanie operatorów, robi się to trochę inaczej niż w C++:
http://www.digitalmars.com/d/2.0/operatoroverloading.html
Własne może się da używając innych stringów. Może dodadzą.

Niegłupie by było wsparcie dla nagłówków i klas C++, ale pomarzyć można. Przydałyby się biblioteki pod ten język, bo sam podobnie jak c++ wiele nie oferuje, ale jest od niego o wiele wygodniejszy.

edytowany 1x, ostatnio: Razi91, 2011-09-27 14:44

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0