[GiM logo]gim.org.pl is down || odświeżony jogger (v.0.4) GiMa

gim photo
Michał 'GiM' Spadliński
programowanie, google, *nix, av, re
last buzz

mini:
  • The Cambist and Lord Iron

    by Daniel Abraham for free @issuu or @POD Castle.

  • Dark Side of C++

    [link]

  • Lost

    No i koniec.

  • Vista vs Open / Save As Dialog Box

    Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.

    Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P

  • Holy fsckin cow

    Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup

  • numery tygodni w Google Calendar

    Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers

  • xps przykłady dokumentów
    Może komuś się przyda: klik
  • D tutorials
    Kilka video tutoriali o podstawach D, różnych edytorach instalacji dmd, tango.
  • niech mi z oczu zejdą

    Każdy problem ma rozwiązanie,
    jeśli nie ma rozwiązania, to nie ma problemu, nie ma problemu

    Ej, człowieku to jest przecież jakiś horror,
    to nie tędy dróżka, jeśli chcesz żeby jakaś fróźka
    poszła z tobą do ee kina

  • powershell - path

    Do zapamiętania:
    PS> $env:path
    PS> $env:path = $env:path + ";c:\blah"

  • Jakiś czas temu...
    ...napisałem, że Programowanie Uogólnione (generic programming), brzmi syfnie, wycofuję się z tego zarzutu, po pierwsze sam zaczynam stosować to sformułowanie, poza tym po dłuższym namyśle brzmi całkiem nieźle, na pewno lepiej niż 'programowanie generyczne', także trochej, zwracam honor : )
  • Kimya Dawson - Loosy Lips
    we won't stop until somebody calls the cops
    and even then we'll start again and just pretend that
    nothing ever happened

Szorty gima (obsolete):
loading...
21
marzec-2010
190232

Moja zabawka: PixelToastereD i coś co ma robić za doki: Release Notes 0x1

catz: [kom.puterowe] [programowanie w D]
tagz: [D bindings] [D programming language] [framebuffer] [język programowania D] [pixeltoaster]
Dodaj swoją opinię
01
maj-2009
214749

This is first of promissed posts about DDL under Linux.

If you haven't read previous post, please do so now, so I won't have to repeat myself.

If you have copy of team0xf ext repo, run hg pull; hg up; if you don't have it yet, grab it:

  • hg clone http://team0xf.com:8080/ext

I've added some new examples in ext/ddl/ddl/Sample subdir.

I've already described how to compile host application in previous post.
Compilation of testPlug01.d and testPlug02_c.c plugins is easy as a pie :]:

  • dmd -c testPlug01.d
  • gcc -c testPlug02_c.c

testHost01.d is a sample host application. It loads plugin calls a function from the plugin, creates an object of class conforming to specified interface, and call some method of that object.

testHost02.d host application declares a variable that will be accessible by a plugin written in C. It loads plugin finds a symbol of a function (declared in that plugin) and executes that function.
Function in plugin changes the variable that is provided by host application

Sorry for short post, but I don't have much time :}.
Currently there is only basic support for object files, some more things are waiting for being comitted, so again, stay tuned :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [DDL] [DDL in Linux] [d] [d programming language] [język programowania D] [plugins in D]
1 komentarz
25
kwiecień-2009
153046

I hear voices, wait a minute, that's not what I've meant.
I've heard there are more and more people interested in DDL (D Dynamic Libraries) under Linux. This is first of short series of posts that will describe some changes I've made in h3r3tic's team0xF's repo.

Pokaż więcej...

catz: [eng.lish] [kom.puterowe] [programowanie w D]
tagz: [d] [d programming language] [ddl] [język programowania D] [linux]
1 komentarz
16
styczeń-2009
000055
Kilka video tutoriali o podstawach D, różnych edytorach instalacji dmd, tango.
catz: [kom.puterowe] [mini.] [Miniblog] [programowanie w D]
tagz: [D] [D programming language] [język D] [programowanie D] [tutoriale] [video]
2 komentarze
14
styczeń-2009
044409

Nice title, huh?
Descent plugin is being cooler and cooler, but you've probably seen it on videos.
One of the things that was driving me mad and kept me away from descent was compilation process.

Java guys probably know apache ant build system (and if they don't they definitely should). I'm going to describe here, how to force eclipse to use descent plugin's ant tasks to build D projects. I'm using this at least for a few months now and I prefer it much more over rebuild method described on Descent page, I was wondering why this method is not described there.

First there are some basic informations, how to install descent with eclipse 3.4, how to set-up a project, the rest is about ant usage.

Eclipse/Descent basic stuff

I'm using Eclipse ganymede since it's better than its predecessors. First quick installation for all the lazy bastards out there:

  1. Go and grab eclipse, I've downloaded IDE for Java Developers since it has ant plugins ready to use.
    (If you have eclipse installed already, you probably could just install apache ant stuff in software updates).
  2. Unpack and start eclipse, choose workspace, go to Help -> Software updates, Available software
    choose Add site and enter descent's site: http://downloads.dsource.org/projects/descent/update-site and OK, it should appear in the middle table, select it and Install,
  3. After few clicks and minutes Descent should be installed and Eclipse will ask you for the start, do so
  4. When it'll start again close the welcome screen, and first of all, turn on D-perspective (Window->Open perspective->Other->D), if it's not there it means you haven't installed descent plugin properly
  5. Next we'll add tango to user libraries to make project configuration simpler. Go to Window->Preferences, choose D->Build path->User libraries, choose New and enter meaningful name (tango? :>), choose Add directory and select directory with your tango lib (I got it under /opt/dmd/include/d),
  6. Go to General->Editors->Text editor->Spelling, and disable spelling engine, otherwise you'll get most of the code red-underlined :]

Now time for some fun stuff.
eclipse descent

  • Choose File->New->Project, select D project, enter name (I've used DSample) and you can click Finish,
  • Right click on your project, choose New->module, enter module name (I've used sample.d) (for simplicity everything will be in default package,
  • Now in editor window type 'main' and press Ctrl+Space (you'll love this shortcut ;)), editor should show suggestions, after hiting Enter you'll have basic main function,
  • If you try typing 'Std' [Ctrl+Space], you'll see there are no fancy proposals, right-mouse-click on your project, choose Build Path->Add Libraries, choose User Libraries, select tango (added in step 5) and click finish,
  • Now after typing 'Std' [Ctrl+Space] you should see some proposals

eclipse descent
Now let's play with ant..

Descent + ant, honey

One night I was playing with descent jar files and I've noticed interesting jar inside descent.core.
Open up your favourite terminal and extract needed jar.

  1. mkdir -p ~/.ant/lib
  2. cd ~/.ant/lib
  3. unzip ECLISPE_DIR/plugins/descent.core_0.5.3.20081231.jar ant_tasks/descent-ant.jar

ECLIPSE_DIR above is of course your eclipse installation dir (~/eclipse in my case :])
Now go back to eclipse, Window->Preferences, Ant->Runtime (Classpath), click Add External JARs and add your ~/.ant/lib/descent-ant.jar archive.
Next go to Tasks menu we'll add two tasks:
I've entered name "descent.D", choose descent-ant.jar from drop-down list, and click on: "/descent/ant/tasks" and choose "D.class"
Now do the same using "descent.DBldNum" and choose "DModuleBuildNumber.class" file.

We're going to create ant build file, but before that let's create build.properites file that will held some basic data in easily editable format.
Press Ctrl+N, choose General->File, and enter build.properties as it's name.
Here is content of my properties file:

  1. compiler.dir = /opt
  2. compiler.type = dmd-linux
  3. src.dir = .
  4. dest.dir = bin

compiler.dir is a path to compiler (without dmd/bin/dmd, descent appends it)
Press Ctrl+N and in filter box type xml, and chose XML, click next, and enter build.xml as a filename, Using bottom tabs choose Source instead of Design
I've created following build.xml (I'm not pasting it here, since this would be quite senseless, but you can take a look at it at codepad.org.
Build file is specific for linux, if I remember correctly my build.xml under windows was simpler than that one.
As you see most of the file is definition of compile macro which takes one parameter (bldtrg). (EDIT: you can find list of all possible parameters for descent.D task here)
Let's forget about that macro for a moment and take a look down at possible targets:

  1. <target name="build-number">
  2.   <descent.DBldNum file="${src.dir}/sample_bn.d" fqn="sample_bn" />
  3. </target>
  4. <target name="compile" depends="build-number" description="Compiles sample">
  5.   <compile bldtrg="sample"/>
  6. </target>

This looks quite clean don't you think?
Now you could right-mouse-click on the build.xml file, choose Run-as ->Ant build file but this is uber-lame.
Instead go to Window->Show View->Other and select Ant. I like to keep this window in lower-wight corner. Double click on any listed target will execute it (along with dependencies).
I have binded Ctrl+Shift+Q A to Show View (View: Ant), this way I can fast switch to ant window :).
eclipse descent

What's cool about it is that you can have multiple build targets (one can build few executables) and have all of them visible and easily accessible.
I'm not going to encourage anybody to use ant, but it's really cool tool, take a while to peek into ant's documentation, especially ant tasks.

catz: [eng.lish] [kom.puterowe] [programowanie w D] [Techblog]
tagz: [d] [d programming language] [descent] [eclipse]
6 komentarzy
04
czerwiec-2008
145754

Znajomi z IRCNetu zarazili mnie tresurehuntem.

Question name Correct entry time
robot 2008-05-20 17:40:44.151252
zip 2008-05-20 17:10:56.126710
network 2008-05-27 22:47:40.954321
primes 2008-06-03 00:19:45.691278

Widać, że pierwsze zadanie rozwiązałem tego samego dnia co drugie. Drugie zadanie rozwiązałem w shellu: find + sed + awk, pierwsze zadanie z użyciem bc -lq i definicją funkcji factorial, network z ręki, bo wpisów nie było jakoś specjalnie dużo, do primes napisałem programik w D który znalazł się na tango wiki

catz: [go.ogle] [kom.puterowe] [programowanie w D]
tagz: [język D] [programowanie] [treasurehunt]
4 komentarze
23
maj-2008
222300

D singleton Dlaczego taki tytuł? Bo singleton, jest powszechnie krytykowanym wzorcem projektowym. Dzieje się tak głównie z powodu początkująch, którzy za wszelką cenę starają się by ich programy były 'obiektowe', a przecież wiadomo, że w programowaniu obiektowym zmienne globalne są ZŁE. Niewiele mysląc młodzi adepci sztuki, opakowują zmienne globalne w singleton i są z siebie zadowoleni ;).
"Singleton nie jest odpowiedzią na zmienne globalne, odpowiedzią jest 'Na jaką cholerę Ci zmienne globalne?'"
Na początek pokażę więc, co można zrobić ze zmiennymi globalnymi w D, a dalej dla tych którzy wiedzą do czego MOŻNA i NALEŻY używać singletona, różne sposoby implementacji w D.

Pokaż więcej...

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [dziedziczenie singletonów] [język D] [programowanie D] [singleton] [singleton in d] [singletony] [singletony i wątki] [wątki]
3 komentarze
25
kwiecień-2008
140108

D
Dawno nic się tu nie działo, głównie dlatego, że nie bardzo mam czas cokolwiek pisać.
Deely pisał jakiś czas temu o wyrażeniach lambda w C#. Dzisiaj trochę o różnych bajerach jakie można robić w D.
Na początek zrobimy sobie małe opakowanie na foreach. Jak zwykle najpierw kawałek kodu, potem jak zwykle pseudo wyjaśnienia.

Pokaż więcej...

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D] [programowanie D]
5 komentarzy
09
luty-2008
131827

Learn to Tango with D
Wreszcie przyszła.

catz: [kom.puterowe] [programowanie w D]
tagz: [book] [d language] [d programming]
3 komentarze
28
listopad-2007
015223

Dziś będzie krótko, jak zacząć programowanie w OpenGLu w D.

Najpierw małe streszczenie z tego co było na warsztatach.
Na trzecich warsztatach D było więcej o klasach, dziedziczeniu, de/kon-struktorach, statycznych de/kon-struktorach, przeciążaniu metod, properties (nie, podobnie jak python nie lubimy setterów i getterów :P, atrybuty/własności w D są banalne do implementacji o czym wspomniałem w pierwszym wpisie). Dalej, o klasach zagnieżdżonych, interfejsach, invariantach (niezmiennikach) obiektów klas, atrybucie scope dla klas, przeciążaniu operatorów, rzutowaniu. uff sporo prawda? :)
Na czwartych warsztatach było natomiast o róznych rodzajach tablic w D o wycinkach tablic i o operatorze konkatenacji, następnie początek zabawy, czyli pierwszy program w OpenGLu.

Zanim jednak stworzymy nasz super ekstra pierwszy projekt, musimy przygotować sobie środowisko pracy :). Zakładam, że tak jak w drugim wpisie o D, masz już zainstalowany kompilator DMD z tango, do tego zainstalowany rebuild.
Potrzebny nam będzie Derelict, czyli zestaw bindingów dla D do różnych (głównie 'multimedialnych' (nie cierpię tego słowa ;)) bibliotek C. Do jego instalacji użyjemy dsssa (można odpalić go z konta użytkownika, wówczas derelict zostanie zainstalowany w podkatalogu w $HOME, jednak instalując jako administrator, zainstalujemy go 'globalnie'):

  • # dsss net install derelict
  • # dsss net install derelictsdl
  • # dsss net install derelictgl

Dsss oidp zapyta najpierw o wybór mirrora, następnie ściągnie za nas, skompiluje i stworzy potrzebne biblioteki, oraz zainstaluje wybrane projekty.
Jeżeli wszystko się powiodło i mamy już dsss'a możemy przystąpić do napisania pierwszego programu. Oto example.d:

  1.  import derelict.opengl.gl;
  2.  import tango.io.Stdout;
  3.  
  4.  void main()
  5.  {
  6.     try {
  7.       DerelictGL.load();
  8.       Stdout ("Successfully loaded the OpenGL shared library.").newline;
  9.     } catch (Exception e) {
  10.       Stdout ("Could not load the OpenGL shared library.").newline;
  11.     }
  12.  }

Plik wrzucamy do jakiegoś katalogu, w tym samym katalogu tworzymy prosty plik dla dsssa, mianowice dsss.conf:

  • [example.d]
  • target=example
  • buildflags=-lldl

-ll jest to flaga dla dsss'a, która sprawi, że przekaże on podaną bibliotekę do linkera, w tym przypadku libdl, potrzebną do dynamicznego ładowania bibliotek.
Teraz wystarczy jedynie:

  • dsss build

I jeżeli mamy potrzebne biblioteki, to dsss powinien skompilować naszą aplikację. Kod jest wzięty z pierwszego tutoriala ze strony dmedia i przerobiony, żeby działał z tango zamiast z phobosem (czyt: zamiana writefln na Stdout ;)).
Polecam zapoznanie się z pozostałymi Tutorialami ze strony dmedia.
Dostosowanie ich do tango nie powinno nastarczyć większych trudności. Wywołanie toStringz można usunąć i dodać na końcu ciągu "\0", lub napisać własną krótką funkcje np taką:

  1.   char[] toStringz(ref char[] str) { return str ~= "\0"; }

Nie testowane, ale chyba ok ;).
Przykłady znajdują również na slajdach z czwartych warsztatów team0xf.

P.S. Blog najprawdopodobniej w najbliższym czasie zostanie mocno zaniedbany, a wpisy jeśli się będą pojawiać to sporadycznie, z tej prostej przyczyny, że nie mam czasu :]

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [OpenGL] [SDL] [język D] [programowanie D]
2 komentarze

Ten wpis miał być, dokończeniem na temat kontraktów (design by contract), ale ponieważ akurat o tym było na drugich warsztatach, więc odsyłam tam :).
Zacznijmy od czegoś prostego, jak w D zadeklarować i zainicjalizować tablicę? Stwórzymy sobie tablicę stringów:

  1.  module arrayofstringstest;
  2.  import tango.io.Stdout;
  3.  
  4.  char[][] pom = [ "aaa", "bbb", "ccc" ];
  5.  
  6.  void main()
  7.  {
  8.     pom ~= "hello";
  9.     pom ~= "world";
  10.     foreach (a; pom)
  11.       Stdout (a).newline;
  12.  }

Przypominam, że literały znaków są w trzymane w pamięci read-only, więc o ile możemy modyfikować sam element pom[0] (czy inne), tak próba zmodyfikowania pom[0][0] skończy się niepowodzeniem (no chyba, że pom[0] został wcześniej podmieniony, na coś innego ;)). Na ten temat wspominałem wcześniej, więc traktuję, że to jasne.

Teraz coś ciekawszego. D, o czym pisałem w pierwszym artykule z tej serii, umożliwia wykonywanie funkcji w czasie kompilacji. Stwórzmy sobie więc tablicę stringów w czasie kompilacji.

  1.  module arrayofstrings;
  2.  import tango.io.Stdout;
  3.  
  4.  char[][] genStrings(int n)
  5.  {
  6.     char[][] ret;
  7.     while(n--)
  8.       ret ~= "XXX";
  9.     return ret;
  10.  }
  11.  const char[][] arrtest = genStrings(10);
  12.  
  13.  
  14.  void main()
  15.  {
  16.     foreach (a; arrtest)
  17.       Stdout (a).newline;
  18.     Stdout.newline;
  19.  }

Operator ~ to jak już wspominałem, operator konkatenacji. W podnym przykładzie, użycie ~= powoduje doklejenie kolejnego elementu do tablicy (intuicyjne prawda? :)).
Skąd pewność, że kompilator rzeczywiście stworzy ten kod w trakcie kompilacji? Po pierwsze, celowo dołożyłem na początku typ składowania const, zmienne które są nim opatrzone muszą być znane w czasie kompilacji, gdyby więc tak nie było kompilator wyrzuciłby błąd. Po drugie, można się o tym łatwo przekonać. Wystarczy linijkę pod deklaracją zmiennej arrtest dorzucić, coś w stylu: const char[] temp=arrtest[10]. Ponieważ wynikowa tablica, ma 10 elementów, a D posiada bounds checking zarówno na poziomie kompilacji (o ile to możliwe) jak i wykonania (chyba, że podamy do kompilatora opcję -release), spowoduje to zatrzymanie kompilacji (numeracja tablic oczywiście od 0), a w komunikacie z błędem zostanie nam pokazana aktualna zawartość tablicy arrtest :).

W tym przypadku wszystkie elementy są takie same, więc nie jest to jakiś powalający efekt. Dużo ciekawszy jest jednak następny przykład, który w czasie kompilacji wygeneruje nam tablicę int'ów, następnie również w czasie kompilacji, posortuje ją i wrzuci do kolejnej zmiennej :).

  1.  module compiletime;
  2.  import tango.io.Stdout;
  3.  
  4.  uint[] genNumbers(int start, int n)
  5.  {
  6.     uint[] ret;
  7.     while(n--) {
  8.       if (start & 1) {
  9.         start >>>= 1;
  10.         start ^= 0xedb88320;
  11.       } else start >>>= 1;
  12.       ret ~= start;
  13.     }
  14.     return ret;
  15.  }
  16.  const uint[] one = genNumbers(0x4d6947, 10);
  17.  
  18.  uint[] gsort(in uint[] tbl)
  19.  {
  20.     uint[] ret = tbl.dup;
  21.     uint k,l;
  22.  
  23.     for (uint i=0; i<ret.length-1; ++i) {
  24.       k = i;
  25.       for (uint j=i+1; j<ret.length; ++j)
  26.         if (ret[j] < ret[k])
  27.           k = j;
  28.       if (k != i) {
  29.         l = ret[k]; ret[k] = ret[i]; ret[i] = l;
  30.       }
  31.     }
  32.     return ret;
  33.  }
  34.  const uint[] two = gsort(one);
  35.  
  36.  void main()
  37.  {
  38.     foreach (a; one)
  39.       Stdout.format ("{:x8}", a).newline;
  40.     Stdout.newline;
  41.     foreach (a; two)
  42.       Stdout.format ("{:x8}", a).newline;
  43.     Stdout.newline;
  44.  }

D ma wbudowane metody do sortowania tablic, wystarczy dorzucić .sort po nazwie zmiennej która jest tablicą i zostanie ona posortowana w miejscu (oczywiście, tablica może być tablicą dowolnych obiektów, wystarczy przeciążyć jedną metodę :)). Metody tej (.sort) jednak nie możemy użyć w czasie kompilacji, (o ograniczeniach dotyczących funkcji wykonywanych w czasie kompilacji można poczytać w dokumentacji) dlatego napisałem krótką i prostą funkcję.
Acha, polecam na pewno ciekawe doświadczenie i umieszczenie jakiegoś const uint x=one[1111]; za deklaracją one, oraz odpowiednio z two za deklaracją two.

Dzisiejszy wpis, miał głównie na celu pokazania tablic asocjacyjnych. W D pojawia się jeden mały problem, otóż nie można zainicjalizować zmiennej która jest AA i która jest zadeklarowana na poziomie modułu. Tak więc poniższy kod nie skompiluje się.

  1.  module aaliteral1;
  2.  import tango.io.Stdout;
  3.  
  4.  int[char[]] two = ["xxx":1, "yyy":2, "zzz":666];
  5.  
  6.  void main()
  7.  {
  8.     foreach (id,val; two)
  9.       Stdout.format ("{} => {}", id,val).newline;
  10.     Stdout.newline;
  11.  }

Bez problemu jednak, można zainicjalizować zmienną typu AA, tak zwanym AA-literałem (to wyrażenie po prawej stronie znaku równości ;)), o ile znajduje się ona wewnątrz funkcji czy metody, tak więc kod poniżej skompiluje się bez problemu.

  1.  module aaliteral2;
  2.  import tango.io.Stdout;
  3.  
  4.  void testowa()
  5.  {
  6.     int[char[]] two = [cast(char[])"xxx":1, "yyyy":2, "zzzzz":666];
  7.     foreach (id,val; two)
  8.       Stdout.format ("{} => {}", id,val).newline;
  9.  }
  10.  
  11.  void main()
  12.  {
  13.     testowa();
  14.  }

Na uwagę zasługuje tutaj jedynie cast(char[]), jest to niezbędne, gdyż kompilator domyślnie przypisuje AA-literałowi typ postaci typ_zew[typ_wew], gdzie zarówno typ_zew jak i typ_wew są typami odpowiednio wartości i klucza, przy czym są one ustalane na podstawie pierwszego elementu AA-literału. Ponieważ typem (literału) "zzz" jest char[3u], kompilator próbowałby zrzutować wszystkie pozostałe klucze do tego typu.
Z tej też przyczyny rzutujemy pierwszy klucz na cast(char[]). To jest bardzo proste, ja tylko utrudniam zrozumienie tego ;). Typ AA-literału jest ustalany na podstawie pierwszego elementu.

Zastanawiałem się, dlaczego tak jest, że nie można zainicjalizować tablicy asocjacyjnej na poziomie modułu. Moim zdaniem (nie wiem czy poprawnym), wynika to z tego jak AA są reprezentowane w pamięci, w trakcie działania (w przypadku D w postaci drzewa binarnego). Tak więc, kompilator nie jest stworzyć odpowiedniej struktury dla takiej zmiennej w czasie kompilacji (tak zgaduję), natomiast umieszczenie takiej zmiennej w jakimkolwiek bloku, powoduje najprawdopodobnie dołożenie kodu, który odpowiednią strukturę stworzy. (Sprawdziłem to i wygląda na to, że moje rozumowanie jest poprawne)
Jeśli jednak potrzebujemy zmiennych typu AA na poziomie modułu, z pomocą przychodzą nam statyczne konstruktory modułów, tak więc następujący kod jest poprawny:

  1.  module aaliteral3;
  2.  import tango.io.Stdout;
  3.  
  4.  const int[char[]] two;
  5.  static this()
  6.  {
  7.     two = ["xxx":1, "yyy":2, "zzz":666];
  8.     two ["xxx"] = 123;
  9.  }
  10.  
  11.  void main()
  12.  {
  13.     foreach (id,val; two)
  14.       Stdout.format ("{} => {}", id,val).newline;
  15.  }

Zwracam jeszcze uwagę, (celowo) poprzedziłem zmienną two słówkiem const. Otóż w D, jeżeli zmiennej (na poziomie modułu) o typie przechowywania const nie nadamy wartości w definicji, możemy modyfikować jej wartość, ale tylko w konstruktorze modułu.

Na ostatnich warsztatach (wkrótce powinny się pojawić materiały z warsztatów) było krótko na temat zagnieżdżonych funkcji i przeciążania funkcji, więcej na temat typów składowania parametrów funkcji, czyli to o czym ostatnio pisałem, kontraktów, funkcji ze zmienną ilością argumentów,lazy evaluation, czyli leniwym wartościowaniu argumentów krótko o linkowaniu z C.
Także te tematy raczej nie będą tutaj poruszane.
To tyle na dzisiaj :) Have phun programming in D :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [compile time function execution] [język D] [programowanie D] [statyczne konstrukotry] [statyczny konstruktor] [tablica asocjacyjna] [tablice asocjacyjne] [wykonywanie kodu w czasie kompilacji]
2 komentarze
10
listopad-2007
153155

Dzisiaj o typach składowania parametrów funkcji, nazywanych również atrybutami. Sporo zastanawiałem się, czy opisy umieścić tutaj, jednak stwierdziłem, że chyba łatwiej i czytelniej będzie w postaci komentarzy w kodzie. Mam nadzieję, że taka forma będzie wam odpowiadać.
Omówimy sobie krótko na przykładach trzy typy składowania in, out, oraz ref (lub jak ktoś woli inout (h3r3tic mnie dziś uświadomił, że inout nie jest aktualnie zalecany i że prawdopodobnie zostanie usunięty, lub zmieni się jego semantyka, także lepiej nie używać). Zastanawiałem się też od którego z nich zacząć, zdecydowałem się na in. Jeżeli ktoś nie miał do czynienia z programowaniem wcześniej to jego zachowanie, może wydawać się dość dziwne, w rzeczywistości jest jednak jasne i proste :).

  1.  import tango.io.Stdout;
  2.  
  3.  // atrybut 'in' mówi, że przekazanie nastąpi przez wartość.
  4.  // zmiany na obiekcie, nie będą widoczne w metodzie wywołującej
  5.  // jednakże...
  6.  void test_int(in int x) {
  7.       x = 70;
  8.       Stdout ("int in test_int ") (x).newline;
  9.  }
  10.  
  11.  // ... z powodu 'płytkiego kopiowania', zmiany na elementach
  12.  // przekazywanego obiektu (czyli wiersz z zamianą znaku) będą
  13.  // widoczne w metodzie wywołującej
  14.  void test_func(in char[] a) {
  15.       a ~= " zonk"; // ponieważ w D ciągi znaków są obiektami
  16.           // ta zmiana powoduje zmianę rozmiaru,
  17.           // i doklejenie ciągu 'zonk' (lokalnie!)
  18.           // jednakże nie niszczy obiektu, który
  19.           // otrzymaliśmy przy wywołaniu funkcji
  20.       a[0] = 'X';
  21.       a[1] = 'X';
  22.       a = "blah!".dup; // niszczymy (lokalnie) orginalny obiekt,
  23.       a[2] = 'X'; // więc te podmiany liter, nie będą
  24.       a[3] = 'X'; // widoczne w metodzie wywołującej
  25.       Stdout ("string in func ") (a).newline;
  26.  }
  27.  
  28.  void main() {
  29.       char[] t = "zażółć gęślą jaźń".dup;
  30.       int val=15;
  31.  
  32.       test_func(t);
  33.       Stdout("string in main ") (t).newline;
  34.  
  35.       test_int(val);
  36.       Stdout ("int in main ") (val).newline;
  37.  }
  38.  

Podając do rebuilda opcję -exec spowodujem odpalenie programu zaraz po kompilacj, tak więc:

  • rebuild -clean -exec test_in.d

Krótkie wyjaśnienie do powyższego kodu. W funkcji main, zaraz za ciągiem znaków widać słówko .dup. Powoduje ono utworzenie kopii stringa. Jest tak dlatego, że w linuxie literały stringów, są w pamięci read-only (jedno zdanie można znaleźć tutaj), więc próba modyfikacji elementów takiego stringa, zaowocuje kochanym SIGSEGV. Stąd potrzebujemy wcześniej skopiować ten string :).
Czas na ref, czyli przekazywanie przez referencję.

  1.  import tango.io.Stdout;
  2.  
  3.  // atrybut 'ref' mówi,
  4.  // że przekazanie nastąpi przez referencje, tak więc
  5.  // wszystkie zmiany których dokonamy na przekazywanym
  6.  // obiekcie będą widoczne w metodzie wywołującej.
  7.  void test_int(ref int x) {
  8.       x = 70;
  9.       Stdout ("int in test_int ") (x).newline;
  10.  }
  11.  
  12.  void test_func(ref char[] a) {
  13.       a ~= " zonk";
  14.       a[0] = 'X';
  15.       Stdout ("string in func ") (a).newline;
  16.  }
  17.  
  18.  void main() {
  19.       char[] t = "zażółć gęślą jaźń".dup;
  20.       int val=15;
  21.  
  22.       test_func(t);
  23.       Stdout("string in main ") (t).newline;
  24.  
  25.       test_int(val);
  26.       Stdout ("int in main ") (val).newline;
  27.  }

Chyba nie trzeba nic tłumaczyć :)
Przejdźmy do out. Out jak się można domyślić oznacza, że parametr jest tylko parametrem wyjściowym, to znaczy że dana funkcja czy metoda ma w nosie wartość jaką tam podamy. Jest przy tym jedna ważna cecha, ale to w komentarzach.

  1.  import tango.io.Stdout;
  2.  
  3.  // najciekawszy atrybut czyli 'out', przekazywanie następuje
  4.  // przez referencje, jednakże, zanim obiekt trafi do metody
  5.  // następuje jego inicjalizacja do wartości domyślnej.
  6.  void test_int(out int x) {
  7.       // zmianna typu int jest domyślnie inicjalizowana 0
  8.       Stdout ("int in test_int ") (x).newline;
  9.  }
  10.  
  11.  void test_func(out char[] a) {
  12.       a ~= " zonk"; // ponieważ na początku zmienna a
  13.           // jest inicjalizowana na pusty ciag,
  14.           // to doklejenie spowoduje tak sklejenie
  15.       // "" razem z " zonk"
  16.       Stdout ("string in func ") (a).newline;
  17.  }
  18.  
  19.  void main() {
  20.       char[] t = "zażółć gęślą jaźń".dup;
  21.       int val=15;
  22.  
  23.       test_func(t);
  24.       Stdout("string in main ") (t).newline;
  25.  
  26.       test_int(val);
  27.       Stdout ("int in main ") (val).newline;
  28.  }
  29.  

Najpierw kawałek kodu, a poniżej opis, jakie zostawiam zadanie ;)

  1.  import tango.io.Stdout;
  2.  
  3.  void test_a() { Stdout ("To jest test_AAA").newline; }
  4.  void test_X() { Stdout ("To jest test_XXX").newline; }
  5.  
  6.  void test_change(in void function() x) {
  7.       Stdout("wywolanie pierwsze w change").newline;
  8.       x();
  9.       x = &test_X;
  10.       Stdout("wywolanie drugie w change").newline;
  11.       x();
  12.  }
  13.  
  14.  void main() {
  15.       void function() a = &test_a;
  16.  
  17.       test_change(a);
  18.       Stdout("wywolanie w main ").newline;
  19.       a();
  20.  }

Małe wyjaśnienie. W main widać deklarację zmiennej a typu void function(), czyli wskaźnik na funkcję typu void, nie przyjmującą żadnych parametrów. Stąd przed test_a pojawia się &, czyli pobranie adresu funkcji test_a.
Podobnie funkcja test_change przyjmuje parametr typu wskaźnik na funkcję (typu void, która nie przyjmuje parametrów). Zadanie jest bardzo skomplikowane, mianowicie potestować, jak ten program będzie się zachowywał, gdy podmienimy atrybut pierwszego parametru funkcji test_change na inoutref oraz out.
Po zrobieniu zadania można zerknąć na ostatni przykład.

  1.  module baker;
  2.  
  3.  import tango.io.Stdout;
  4.  
  5.  void baker(inout int b)
  6.  {
  7.       assert(b < 0x10000, " RANY! b jest większe od 65535! co my teraz zrobimy?! ");
  8.       b = 666;
  9.  }
  10.  
  11.  int main()
  12.  {
  13.       int x = 0x5ac4;
  14.  
  15.       Stdout.format ("{:x}", x).newline;
  16.  
  17.       baker(x);
  18.       Stdout.format ("{:x}", x).newline;
  19.  
  20.       x = 0x12345;
  21.       baker(x);
  22.       Stdout.format ("{:x}", x).newline;
  23.  
  24.       return 0;
  25.  }

Jedynym nowym elementem, który się tu pojawia jest assert. assert podobnie jak w C sprawdza, czy podany warunek jest prawdziwy. Jeśli nie jest, 'rzuca' on wyjątkiem (który można oczywiście przechwycić).
assert(0); można używać, do oznaczania fragmentów kodu, do których program nie powinien dotrzeć. Pierwszą myślą jest, "jak to możliwe, jak może być miejsce, gdzie program ma nie dotrzeć?", jednak chociażby w przypadku budowania bardziej skomplikowanych parserów, jest to dość przydatne. Więcej na temat Contract Programming w którymś z kolejnych odcinków

Do powyższego przykładu, proszę spróbować zmienić inout w funkcji baker, na out i sprawdzić (albo jeszcze lepiej przewidzieć) jaki będzie wynik działania.

Omówiłem tylko trzy podstawowe typy składowania, jest ich jednak więcej i mają różne ciekawe zastosowania. Zaciekawionych odsyłam do dokumentacji:
invariant, const oraz final (const w D jest typem składowania, a nie atrybutem dla typu, więcej na ten temat oraz porównanie do C++ tutaj
lazy (warto wspomnieć, że typ składowania lazy został zasugerowany przez Tomasza 'h3r3tic'a Stachowiaka z Team0xf).
Podane w linkach typy składowania, pewnie pojawią się kiedyś w przykładach ;)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [in] [inout] [język D] [out] [ref] [storage class]
2 komentarze
09
listopad-2007
022143

Obiecany przykład, a potem ciut wyjaśnień.

  1.  module pierwiastki;
  2.  
  3.  private import tango.io.Stdout;
  4.  private import tango.math.Math;
  5.  private import tango.text.convert.Float;
  6.  
  7.  void main()
  8.  {
  9.       double a = 1.0, b = 1.0, c = 0.0;
  10.       double delta = b*b - 4*a*c;
  11.  
  12.       if (delta<0) {
  13.           Stdout ("PUKPUK!");
  14.       } else {
  15.           double x1 = (-b - sqrt(delta)) / 2*a;
  16.           double x2 = (-b + sqrt(delta)) / 2*a;
  17.           Stdout ("pierwiastki: "~toUtf8(x1)~", "~toUtf8(x2)).newline;
  18.           // to samo inaczej
  19.           Stdout.format ("pierwiastki {}, {}", x1, x2).newline;
  20.       }
  21.  
  22.  }

W D na projekty buduje się z cegłówek zwanych modułami. Każdy plik stanowi osobny moduł. Linijka module jest opcjonalna (w podanym wyżej przykładzie wręcz zbędna). Jeżeli w pliku ma się ona znajdować, nie może przed nią być nic innego (poza komentarzami ow coz :D). Domyślnie nazwa modułu jest tworzona z nazwy pliku po usunięciu rozszerzenia. Moduł dostarcza przestrzeń nazw dla wszystkiego co się z nim znajduje.

W pythonie jeżeli importujemy tak:

  • import math

To moduł math jest wrzucany do aktualnej przestrzeni nazw statycznie, to znaczy nazwy wszystkich wrzucanych obiektów, są poprzedzone nazwą modułu, tym samym by odwołać się do jakiegokolwiek elementu tego modułu trzeba podawać pełną nazwę (np math.log).
W D jest odwrotnie domyślnie obiekty danego modułu są wrzucane do bezpośrednio do aktualnej przestrzeni nazw, (dlatego po import tango.io.Stdout nie musimy się odwoływać do obiektu Stdout tego modułu przez: tango.io.Stdout.Stdout (tak dwa razy Stdout, bo pierwsze to nazwa modułu, a drugie nazwa obiektu), lecz przez samo Stdout.
W przypadku większych projektów może to prowadzić do kolizji nazw, chcąc więc tego uniknąć (i wymusić zachowanie takie jak w pythonie) należy poprzedzić nazwę modułu słowem static.
Domyślnie importy w D są prywatne, to znaczy jeśli moduł A imporuje moduł B, który z kolei importuje moduł C, to moduł C nie jest widoczny bezpośrednio w module A. Dla ułatwienia rozpatrzmy następujący przykład:

  1.  // pierwszy.d
  2.  module pierwszy;
  3.  private import tango.io.Stdout;
  4.  
  5.  // drugi.d
  6.  
  7.  import pierwszy;
  8.  
  9.  void main()
  10.  {
  11.       Stdout ("test"); // ŹLE !! import w pierwszym jest prywatny
  12.       tango.io.Stdout ("test"); // ŹLE !! as above
  13.       pierwszy.tango.io.Stdout ("test"); // OK
  14.  
  15.  }

Proste prawda? :)
Do tego zostają jeszcze importy przemianowane i wybiórcze, ale w tym momencie odsyłam do dokumentacji :)
Doszliśmy więc do tego, że w pierwszym przykładzie mamy niepotrzebną linijkę import i niepotrzebne kwalifikatory private.
Następnie w funkcji main mamy kilka zmiennych typu double. Po listę typów i ich rozmiary (bo jak mówiłem w D zmienne mają ustalone rozmiary) odsyłam tutaj.

WAŻNA UWAGA
W D przy deklarowaniu kilku zmiennych, muszą być one tego samego typu (zdaje się, że wcześniej kompilator przed tym nie ostrzegał, teraz traktuje to jako błąd)!
To znaczy:

  1. int[] a, b, c; // deklaruje 3 tablice typu int, a nie jedną tablicę i dwa inty!
  2. int* a, b, c; // analogicznie deklaruje 3 wskaźniki na zmienne typu typu int!
  3. int a, *b,i c; // ŹLE!

Wracając do pierwszego kodu, widzimy wiec kilka zmiennych, liczenie delty, dalej w ifie liczenie pierwiastków funkcji kwadratowej z wzorów Viète'a. sqrt() jest metodą z modułu tango.math.Math, liczącą oczywiście pierwiastek, toUtf8 jest metodą z modułu tango.text.convert.Float zamieniająca float na postać tekstową.
~ jest w D operatorem konkatenacji.
Niżej jest identyczne wypisanie ale przy użyciu formattera, podobnego do tego z .neta, szczegóły tutaj.

Team0xf

Team0xf prowadzi warsztaty języka D (w Toruniu). Na stronie Warsztatow znajdziecie opis jak zainstalować dmd z phobosem, materiały z pierwszych warsztatów: filmiki, całą prezentację oraz przykładowe programy. Warsztaty będą się odbywać prawdopodobnie co tydzień i mniej więcej co tydzień na ich stronie pojawiać się będą nowe materiały.


Ponieważ nie zamierzam w żaden sposób konkurować z tym co oni prezentują (tym bardziej, że prezentują wyższy poziom :D), gorąco zachęcam do odwiedzania ich strony.
Jeżeli coś jeszcze będzie się pojawiać na joggu na temat D, to coś, czego (jeszcze) na warsztatach nie było, albo coś czego nie było i nie bedzie ;).
To tyle na dzisiaj, miłej nocy z D :)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D]
5 komentarzy
09
listopad-2007
002222

Jak wspomniałem w pierwszej części istnieją dwa kompilatory: oficjalny rozwiajny przez digitalmars - dmd oraz nakładka na gcc - gdc. Do tego istnieją trzy biblioteki standardowe phobos, rozwijana przez community tango, oraz z ostatnich warsztatów Team0xf (o nich później) dowiedziałem się, że istnieje coś takiego jak libd.

Tutaj będzie poruszona jedynie kombinacja DMD+tango i tylko pod linuxem. DMD dlatego, że zazwczaj jest o krok dalej niż gdc, to digitalmars definiuje kierunek rozwoju D, jednak szeroko pojęte 'D community' ma wpływ na rozwój języka (warto jednak zerknąć na gdc, gdyż poprzez użycie gcc, daje on czasem lepszą optymalizację). Warto może w tym miejscu wspomnieć, że dmd pod linuxem z gcc ale jedynie w celu linkowania. Pod windowsem korzysta z kompilatora C digitalmars - dmc.
Tango, jeśli się nie mylę wyrosło z dwóch projektów ares oraz mango. Dlaczego tango? Głównie dlatego, że mi bardziej przypadła do gustu niż phobos ;)
Jeżeli ktoś jest zainteresowany spróbowaniem phobosa, to pod koniec artykułu w następnym wpisie będzie małe wyjaśnienie gdzie znaleźć ładny opis instalacji i użycia

Instalacja potrzebnego softu

Będziemy potrzebować dmd i tango, które można ściągnąć w jednej paczce. Dodatkowo do budowania będzie nam potrzebny Rebuild który jest częścią projektu DSSS. (Rebuild jest nam potrzebny, ze względu na pewne problemy z linkerem. Ponadto ułatwia on kompilację dużych projektów. Na dokładkę DSSS zmierza ku temu, by zostać ujednoliconym systemem pozyskiwania, budowania, instalowania i konfiguracji projektów stworzonych w D). Ja wrzucam dmd+tango do /opt/dmd a dsss'a do /opt/dsss rób jak chcesz.

  • wget http://downloads.dsource.org/projects/tango/0.99.2/tango-0.99.2-bin-linux-dmd.1.021.tar.gz
  • wget http://svn.dsource.org/projects/dsss/downloads/0.73/dsss-0.73-dmd-gnuWlinux-x86.tar.gz
  • mkdir -p /opt/dmd /opt/dsss
  • tar -xvzf tango-0.99.2-bin-linux-dmd.1.021.tar.gz -C /opt/dmd --strip 1
  • tar -xvzf dsss-0.73-dmd-gnuWlinux-x86.tar.gz -C /opt/dsss --strip 1

Okej zrobione. Pozostaje dodać /opt/dmd/lib do /etc/ld.so.conf i wydać polecenie ldconfig oraz dodać do PATH /opt/dmd/bin oraz /opt/dsss/bin. Jeśli to czytasz, ufam że sobie poradzisz ;)

And there was no Software yet. But God created programs; small and big... And told them - Go and multiply yourselves and fill all the Memory.

Oczywiście zaczniemy od hello world. Normalnie rebuild dość sporo plików obiektowych, więc będziemy podawać do niego opcję -oqlib, żeby wszystkie pliki obiektowe wrzucał do katalogu lib w katalogu w którym kompilujemy program.
Program w D zaczyna się od funkcji main, która ma 4 określone deklaracje, obowiązują proste zasady:

  • funkcja main musi być typu void lub int, zwracana wartość jest przekazywana do systemu operacyjnego,
  • jeżeli typem zwracanym przez main jest void, wartością zwracaną do systemu jest 0,
  • main może przyjmować jeden argument typu char[][], lub nie przyjmuje wcale,

Powyższe zasady owocują w czterech możliwych deklaracjach funkcji main. My użyjemy najprostszej.

  1.  import tango.io.Console;
  2.  
  3.  void main()
  4.  {
  5.       Cout ("Zażółć gęślą jaźń").newline.append("druga linia").newline;
  6.  }
  • # Kompilujemy nasz super program:
  • rebuild -oqobj hello.d

Tak jak wspominałem, pliki obiektowe wrzucamy do katalogu obj. Program wynikowy nazywa się hello po odpaleniu możemy podziwiać efekty naszej żmudnej pracy ;).
W pierwszej linijce importujemy moduł (o modułach za chwilę) Console, jego dokumentację można znaleźć tutaj. Console jest klasą niskopoziomową i akceptuje input tylko w postaci tekstu w UTFie. (Możemy jednak zmusić ją, do wypisania tekstu w iso, konwertując go na hexy: "Za\xbf\xf3\xb3\xe6 g\xea\xb6l\xb1 ja\xbc\xf1" :>)
Dla ciekawych:
Jeśli zajrzymy do dokumentacji zrozumiemy co dzieje się dalej (a jeśli nie zrozumiemy to się domyślimy ;)). Cout jest statyczną klasą (o tym też może później) typu Output. Wywołanie Cout("tekst") powoduje tak na prawdę wywołanie Cout.append("tekst"); (o tym też później).
Ponieważ metoda append, zwraca obiekt typu Output możemy całość (Cout.append(...)) potraktować jako klasę i wywołać jedną z jej metod: newline (w D metody które nie mają parametrów nie muszą mieć nawiasów przy wywoływaniu). Ponieważ metoda newline również zwraca obiekt typu Output, znów możemy wywołać na nim metodę owej klasy. Jeżeli więc komuś ułatwia to czytanie (chyba może jedynie zaciemnić), można to zapisać tak:
(((Cout ("Zażółć gęślą jaźń")).newline()).append("druga linia")).newline(); // fuj! :>

Tu miał być jeszcze jeden przykład, ale postanowiłem, że zostanie wydzielony do osobnej części ;)

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [język D] [pierwszy program] [programowanie]
2 komentarze
09
listopad-2007
001829

Większość z joggerowiczów słyszała chociaż o pythonie czy rubym. Niektórzy nawet piszą bardzo ciekawe artykuły na temat jednego bądź drugiego. Serią kilku artykułów chciałbym natomiast przybliżyć joggerowiczom mniej popularny język -- D. Mam nadzieję, że uda mi się skłonić chociaż kilka (no choćby jedną) osobę do zapoznania się z tym językiem.
Na wstępie zaznaczam, że nie jestem guru tego języka ;). Artykuł będzie ciut przydługi, prawdziwa przygoda zacznie się dopiero od następnego razu.

D jest językiem mającym poniekąd związek z C i C++. Mającym bo oprócz pewnych podobieństw w składni różni się od nich znacznie. D jest tak zwanym językiem wieloparadygmatowym umożliwiającym: programowanie impreatywne, programowanie obiektowe oraz metaprogramowanie (odsyłam do angielskiej wiki, bo na polskiej ten artykuł praktycznie nie istnieje ;)).

Przede wszystkim: D jest językiem kompilowanym do kodu natywnego (chociaż może być również interpretowany), przy czym szybkość kompilacji bije na głowę szybkość kompilatorów C czy C++. Jeżeli przyjmiemy, że kod w C++ wykonuje się szybciej niż kod w Javie (proszę o nie prowadzenie flame'a na ten temat w komentarzach :>), tak kod w D dorównuje szybkością C++ a nawet przewyższa.

D ma statyczne sprawdzanie typów. W D typy zmiennych podstawowych mają określone rozmiary w przeciwieństwie do C czy C++. D ma wbudowane typy zmiennych, które np w C++ są dostarczane przez biblioteki. Są to m.in: Tablice dynamiczne, stringi (ciągi znaków niespecjalnie pasuje, a każdy programista wie co to string), słowniki, liczby urojone. (Podobnie jak w pythonie, prawda?). D posiada dwie trzy (odmienne) biblioteki standardowe (więcej na ten temat w przyszłym odcinku). Istnieją dwa kompilatory D: oficjalny dmd, oraz nakładka na gcc - gdc.

Nieco więcej o cechach D (część może w chwili obecnej być niezrozumiała, ale może wyjaśni się w przyszłości) (acha, * oznacza, że może kiedyś więcej na dany temat ;)):
  • Różne:
    • Wbudowany garbage collector, ale nie trzeba z niego korzystać,
    • wersjonowanie, debugowanie i unittesty wbudowane w język,
    • Aliasowanie typów (odpowiednikiem alias (dla typów) w D jest typedef z C/C++, aliasowanie typów ma na celu jedynie skrócenie pisania, nic więcej),
    • Silne typowanie z użyciem typedef'a (szczegóły *),
    • foreach :)
    • stringi w switchu() (tego mi często brakuje w C ;/),
    • Wbudowany assembler (tak, nie tak jak w C, gdzie składnia asemblera jest zależna od kompilatora ;/), składnia jest określona, zestaw instrukcji jest poszerzany, o ile się nie mylę, w planach są kolejne architektury (na razie jest x86 to chyba oczywiste :>),
    • Dostęp do bibliotek C (nie oznacza to jednak, że można korzystać bezpośrednio z plików .h),
    • Możliwość kontroli wyrównania w pamięci elementów struktur,
    • SRC może być w unicodzie, IO w unikodzie,
    • Tworzenie dokumentacji z komentarzy (ddoc)
  • Funkcje:
    • Delegaty funkcji (w .necie też są),
    • przeciążanie funkcji,
    • typy składowania parametrówargumentów fukcji,
    • zagnieżdżone funkcje (sic!),
    • literały funkcji i delegat (w polskim zaczyna się przyjmować słowo literał, choć ja bym chyba wolał funkcje explicite, strinig explicite itd, ale to taka tam moja fanaberia :>),
    • bezpieczne typowanie argumentów funkcji ze zmienną ilością afgumentów (uff koszmarnie to po polsku wygląda, chodzi o znane z C funkcje: blabla(char *s, ...), które w C nie mają możliwości sprawdzania typów),
    • 'leniwy' typ składowania dla argumentów umożliwiający 'Leniwe' wartościowanie argumentów funkcji,
    • wykonywanie funkcji w czasie kompilacji (sic!) (z pewnymi ograniczeniami, ale jednak) (Oh yeah! można zrzucić np precomputing na kompilator, a niektórzy evil haxorzy piszą tak całe programy :>),
  • Tablice: łatwa zmiana rozmiaru (zazwyczaj chodzi nam o rozszerzanie :]), znany z pythona (strzelam, że z ruby'ego też Array slicing, bounds checking (sprawdzanie zakresu, jakby było niejasne :]), literały tablic, tablice asocjacyjne (indeksem AA w D może być cokolwiek)
  • OOP: moduły, interfejsy, zagnieżdżone klasy, klasy wewnętrzne (taka wariacja klas zagnieżdżonych), przeciążanie operatorów, kowariancja zwracanych typów (przez przeciążoną metodę w klasie dziedzicącej), proste 'właściwości' (w pythonie jest do tego property() w javie i (chyba) .necie settery i gettery, w D nie trzeba nic robić :])
  • OOP: D nie wspiera dziedziczenia wielobazowego (zwanego też dziedziczeniem wielokrotnym, choć ta nazwa sugeruje więcej niż nazwa 'wielobazowe').
  • Generic Programming (a jakże mogłoby zabraknąć!) (na polskiej wiki, użyte jest programowanie uogólnione, które przepraszam za wyrażenie wydaje mi się maksymalnie syfne :>)).
    • Szablony klas, szablony funkcji, uszczegóławianie typów parametrów szablonowych (niekoniecznie do konkretnych typów) (*), liczbowe parametry szblonów (*), aliasowanie parametrów szablonów (umożliwia to parametryzowanie szablonów dowolnym innym symbolem z D: nazwami, nazwami modułów, nazwami szablonów, instancji szablonów), szablony ze zmienną ilością parametrów (a przez to również argumentów).
    • mixiny szablonów i mixiny - podobne nazwy, ale to dwie zupełnie różne rzeczy, mixiny pozwalają w pewien sposób generować kod w czasie kompilacji,
    • static if - to chyba konstrukcja specyficzna dla D, w pewien sposób przypomina ifdef z C, ale tylko przypomina :]. static if (zamykający else if oraz else również są statyczne) pozwala na warunkową kompilację, ale jest to normalny element języka, więc musi być poprawny składniowo, po drugie może być używany w szablonach, więcej szczegółów (*),
    • assert i static assert - assert wiadomo do czego służy, static assert natomiast sprawdzany jest w czasie kompilacji (*),
    • typeof - ma inne zastosowanie niż w innych językach, do sprawdzania typów jest linijkę niżej, (*),
    • wyrażenia is - pozwalają na różne sprawdzanie typów i nie tylko w czasie kompilacji, nie będe teraz wnikał, (*) :],
  • Niezawodność:
    • Contract programming - w łatwy sposób można stawiać wymagania dla wejścia i wymagania dla wyjścia, które się odrzuca budując wersję do wypuszczenia,
    • statyczne konstruktory i destruktory (zarówno dla klas jak i modułów) - wywoływane odpowiednio prze wejściem do main i po opuszczeniu main,
    • try/catch/finally, do tego dochodzi jeszcze scope ale (*)
    • synchronized - dla wątków

To oczywiście nie wszystko, starałem się dużą przedstawić dużą część możliwości, stąd ten chaos :> Co dalej? Gdzie udać się z tego miejsca? Oto garść linków:

catz: [kom.puterowe] [programowanie w D] [Techblog]
tagz: [D] [D programming language] [D programowanie] [język D] [krótko o D]
9 komentarzy