Dziś jest sobota, 31 lipca 2010 roku (z kalendarza...)

Jak mogłoby wyglądać PHP?

Icon

27.01.2010, 17:45

PHP

Komentarze (36)

Powrót

Ostatnio w wolnych chwilach trochę zastanawiałem się, jak mógłby wyglądać następca PHP. Nie chodzi mi o jakieś mityczne PHP 7, ale o zwyczajne wzięcie się i zaprojektowanie tego języka od zera, na wstępie wyrzucając wszystkie irytujące niedociągnięcia. W tym wpisie chciałbym podzielić się wynikami tego eksperymentu myślowego.

PHP kontra reszta świata

Na PHP wieszają psy prawie wszyscy, a w szczególności ludzie, którzy bardzo mało w nim programowali lub dawno zarzucili swe więzy z tym językiem. Dlatego przed rozpoczęciem zabawy postanowiłem zebrać do kupy wszystko, co mnie w tym języku wkurza, a co jest plusem, zwłaszcza w kontekście moich ostatnich zabaw z Rubym.

Minusy:

  1. Mega-bałagan w bibliotece standardowej.
  2. Niewykorzystywanie możliwości języka przez niego samego. Dlaczego 95% rozszerzeń, nawet jeśli powstały już za czasów PHP 5, generuje błędy przy pomocy Warning, kiedy od sześciu lat są wyjątki, albo wynajduje koło od zera w tej dziedzinie?
  3. Naleciałości historyczne w semantyce samego języka, które trochę utrudniają pisanie.
  4. Jak wyżej, ale w składni.
  5. Wiele bardzo potrzebnych dodatków zostało dodanych niedawno, więc nie do końca działają poprawnie. Przykładem jest nowy odśmiecacz pamięci, który byłby fajny, gdyby nie wycieki pamięci oraz wykrzaczanie interpretera na tak popularnych aplikacjach, jak PHPUnit.
  6. Brak wielowątkowości.
  7. Niespójny system typów.

Plusy:

  1. Elegancka składnia wywodząca się z rodziny C. Przynajmniej ja osobiście uważam ją za dużo lepszą i bardziej precyzyjną, niż wynalazki w takim Rubym.
  2. Świetny model obiektowy - jest tylko kilka drobnych braków, które można doszlifować, lecz poza tym korzysta się z niego bardzo przyjemnie.
  3. Pojedyncze, dobrze zaprojektowane rozszerzenia: PHAR, PDO
  4. Skalowalność - dobrze sobie radzi z prostymi skrypcikami, by coś sprawdzić lub policzyć na szybko, jak i z większymi aplikacjami.

Teraz możemy przejść do zabawy w poprawianie PHP.

Zmienne...

Ze zmiennymi w PHP mamy trochę shizofreniczną sytuację. Teoretycznie można je używać od razu bez potrzeby deklarowania czy inicjacji, ale w praktyce trzeba to robić, aby nie zostać zawalonym setkami komunikatów Notice. To, czy mają się one wyświetlać czy nie, zależy od ustawień konfiguracji i widzimisię administratora i naprawdę jest ciężko, gdy trzeba skorzystać ze skryptu, którego twórca sobie sprawę olał. Dlatego podstawowa zmiana to wymuszenie zainicjowania zmiennej przed użyciem pod groźbą rzucenia wyjątku. Nie jest ważne, gdzie to robimy, jak w Javie. Po prostu w momencie, gdy odwołujemy się do zmiennej, interpreter musi mieć w pamięci informację, że jest do niej jawnie przypisana wartość.

System typów

System typów można znacząco uprościć zauważając, że nie ma żadnego technicznego uzasadnienia, dla którego tablica z haszowaniem jest "tablicą", a wszystko inne, wliczając w to pozostałe struktury danych - obiektem. W języku potrzebne są właściwie dwa typy:

  1. Scalar - typ prymitywny: string, integer, float, boolean
  2. Object - typ złożony, czyli obiekt

Nie jestem zwolennikiem wciskania obiektów w każdy najmniejszy zakamarek języka. Ma to duży sens przy rozważaniach akademickich, ale w praktyce rodzi wiele trudnych pytań, na które nie ma dobrej odpowiedzi. Przypuśćmy, że integer byłby typem obiektowym? Jak powinienem rozumieć zapis 13? Czy jest to obiekt liczbowy z wartością "13", a może obiekt "13"? Czy dwa obiekty liczbowe o wartości 13 są tym samym czy czymś innym? Jeśli obiekt liczbowy, to czym jest pojęcie "wartości", skoro w języku wszystko jest obiektem? Obiekt powinien reprezentować byt, więc dlaczego "13" nie jest obiektem reprezentującym liczbę 13 poprzedzonym przez obiekt "12", a następującym po "14"? Jak to się ma do efektów ubocznych funkcji, kiedy obiekty kopiowane są przez referencję, a nie przez wartość? I najważniejsze: na co tyle obiektów w pamięci?

System typów nie musi być ścisły, jak w Javie, stąd nie byłoby problemów z umieszczaniem wartości prymitywnych w strukturach danych ani przekazywaniem ich poprzez argumenty:

function foo($foo, scalar $bar, ClassName $joe)
{
   // ...
} // end foo();

W obrębie typu 'scalar' interpreter zachowywałby się tak samo, jak w PHP, automatycznie rzutując wartości tam, gdzie to konieczne. Jednak przejście z obiektu na typ skalarny lub na odwrót bez jawnej konwersji możliwe by nie było. Praktyka pokazuje, że jest to źródłem wielu błędów, a przy okazji złych praktyk programistycznych, jak np. funkcja("$zmienna").

Skoro już wspomnieliśmy o praktykach programistycznych, warto zastanowić się nad problemem niechlujnego pisania. Twórca Pythona postanowił leczyć nierobienie wcięć, czyniąc je integralnym elementem języka. W poprawionym PHP wyrzuciłbym interpolację ciągów tekstowych: "tekst $zmienna tekst". Nie jest ona do niczego potrzebna - dokładnie ten sam efekt można osiągnąć kropką i zwyczajnym scalaniem, a jest to nawet wydajniejsze i przynajmniej da się uniknąć takiego potworka, jak powyżej.

W obrębie typów prymitywnych wprowadzone mogłyby być następujące zastrzeżenia:

  1. Długość typu liczbowego zależy od platformy, jednak przy próbie jego przekroczenia liczba jest w tle konwertowana na typ "big integer", jak w Rubym. Użycie systemu 64-bitowego powinno po prostu znacząco przyspieszyć obliczenia na dużych liczbach.
  2. Ciągi tekstowe zakodowane są wewnętrznie w UTF-16; cały język wykorzystuje to kodowanie natywnie. Dlaczego UTF-16? Jest to kompromis między zwięzłością UTF-8 dla języków anglosaskich, a przydatnością do zapisu alfabetów nieeuropejskich. Podobne założenie przyjęte jest w Javie.

Rozszerzenia składni

Pierwsza przydatna rzecz to blok 'finally':

try
{
   // blok krytyczny
}
catch(Exception $wyjatek)
{
   // obsługa wyjątku
}
finally
{
   // sprzątanie, obowiązkowe
   // bez względu na to czy rzucamy wyjątek czy nie
}

Problem sprzątania po wyjątkach jest dość poważny. W szczególności wyskoczenie ze środka dość ważnego procesu mogłoby zostawić go w stanie niespójnym i uczynić dany kawałek kodu niezdatnym do użycia.

Wprowadzenie cech do języka, znanych pod angielską nazwą "traits", co nawiasem mówiąc już jest zaproponowane do PHP. Cecha to przydatny sposób na ominięcie braku wielodziedziczenia. Luki po nim nie łatają interfejsy. Cecha to zwyczajny zbiór metod i pól, które na etapie kompilacji są "w tle" doklejane do danej klasy, dzięki czemu możliwe jest wstrzyknięcie także implementacji. Ważną własnością cech jest ich prostota - rodzą one dużo mniej problemów niż domieszki, zwłaszcza w przypadku konfliktów nazw.

trait Foo
{
   public function metoda()
   {
      echo 'Hello!';
   } // end metoda();
}
 
class Bar
{
   use Foo;
 
   // kod...
}

Język oczywiście posiadałby przestrzenie nazw, ale skoro nie jesteśmy ograniczeni wsteczną kompatybilnością, wykonujemy roszadę:

  • do łączenia ciągów tworzymy operator ~,
  • zwolnioną kropkę wykorzystujemy jako separator przestrzeni nazw.

Co więcej, dodajemy polecenie import do importowania klas. Byłaby to część zupełnie przeprojektowanego mechanizmu odnajdowania plików z kodem. Prymitywne require oraz include_path po prostu nie sprawdza się w sytuacjach, gdy różne klasy mogą mieć różne przeznaczenie. We frameworkach chcemy, aby biblioteki były elegancko dołączane z określonego katalogu, ale klasy kontrolerów i modeli rządzą się własnymi prawami. Tutaj zastosowałbym pomysł rodem z Open Power Libs. Interpreter dostaje nazwę klasy oraz przestrzeni nazw do załadowania. Bada sobie więc pierwszy element tej przestrzeni i sprawdza w katalogu, jaka ścieżka jest dla niego przewidziana oraz ew. jaka zewnętrzna ładowarka:

Loader::addPath('framework', '../lib/');
Loader::addPath('controller', '../app/frontend/controllers');
Loader::register('controller', myCustomLoader);
 
// Ręczny import
import framework.logs.Logger;
 
// Autoładowanie
$foo = new controller.Index;
 
// Dołączanie pliku z luźno wstawionym kodem
// wyłącznie ścieżki relatywne lub bezwzględne
require('../plik.php');

Zaletą tego podejścia jest wydajność. include_path przy skanowaniu po kolei sprawdza wszystkie katalogi, a operacje dyskowe kosztują, zwłaszcza gdy wszystko musi przejść jeszcze przez naszą dodatkową ładowarkę. Dlaczego interpreter ma skanować wszystko, kiedy może po prostu przeczytać, o jaką przestrzeń nazw nam chodzi i od razu skoczyć do wymaganej lokalizacji?

Niedociągnięciem PHP jest brak kontroli nad elementami statycznymi klas. Nie ma ani statycznego konstruktora, ani możliwości ewentualnego wyczyszczenia stanu, co bardzo utrudnia debugowanie. Dlatego powitałbym takie rozwiązanie:

class Foo
{
   static private $foo;
 
   static function __construct()
   {
      echo 'Konstruktor statyczny';
   } // end __construct();
 
   static function __destruct()
   {
      echo 'Destruktor statyczny';
   } // end __destruct();
} // end Foo;

Do tego pojawiłby się specjalny blok 'static' kontrolujący zakres dostępności elementów statycznych. Rozpatrzmy przykład:

static
{
  echo Klasa::$foo++;
}
 
static
{
  echo Klasa::$foo++;
}

Proces tworzenia i niszczenia elementów statycznych nie byłby już związany z początkiem i końcem działania skryptu, ale z blokiem static. W momencie pierwszego odwołania do elementu statycznego klasy wywoływany byłby statyczny konstruktor, a przy jego opuszczaniu - destruktor. Gdy interpreter wejdzie do drugiego bloku, zainicjuje statyczną część klasy od nowa. Domyślnym blokiem static byłby cały skrypt, przez co bez korzystania z tej funkcjonalności wszystko działałoby po staremu. Za to pakiety do testowania jednostkowego mogłyby bardzo łatwo zapewnić izolację, po prostu wykonując każdy test we własnym bloku static. Byłby to też sposób na kontrolowanie życia singletonów. Jako rozszerzenie można by podawać w nawiasie, jakich klas ma dotyczyć statyczny blok: static(Klasa1, Klasa2, Klasa3){ ... }.

W obiektach doszłoby do małego uporządkowania paru drobiazgów. Najważniejszą zmianą byłoby ustalenie późnego wiązania statycznego jako domyślnego, gdyż obecnie jest tu pewna niekonsekwencja - w obiektach mamy pełen polimorfizm, a w elementach statycznych już nie. Uściślone zostałyby także niewłaściwe praktyki programistyczne.

Ostatnia ciekawa zmiana to wprowadzenie programowania kontraktowego. Chodzi o dodanie możliwości definiowania kontraktów mówiących o tym, jaki jest spodziewany stan wejściowy i jaki wyjściowy:

public function foo($argument)
in
{
   assert($argument instanceof Foo || $argument !== null);
}
out($result)
{
   assert($result != null);
}
body
{
   return $foo->processSomething();
}

Identyczny patent zastosowany jest w języku D, jednak tam kod kontraktów kompilowany jest na życzenie. W języku interpretowanym byłby to dodatkowy (spory) narzut wydajnościowy, dlatego należałoby najpierw pomyśleć, jak sobie z tym poradzić.

Ostatnie dodatki służyłyby do szybkiego tworzenia struktur danych:

// tablica z haszowaniem
$foo = new ['foo' => 'bar', 'joe' => 'goo'];
 
// słownik
$bar = new {'foo', 'bar', 'joe'};
 
// tablica o stałym rozmiarze
$joe = new 15:['foo', 'bar', 12 => 'joe'];

Biblioteka standardowa

Kluczem w bibliotece standardowej jest porządek i niemal pełna obiektowość. Funkcjami pozostałyby podstawowe operacje na typach prymitywnych, ale zostałyby one umieszczone w odpowiednich przestrzeniach nazw, np. math.sin() i logicznie ponazywane. Poza tym cała reszta opierałaby się na obiektach: bazy danych, XML, przetwarzanie obrazków, wyrażenia regularne i co tam jeszcze sobie wymyślimy. Wszystkie błędy raportowane jako wyjątki, co wspólne, jest konfigurowalne przez wspólne API i nie ma czegoś takiego, że każde rozszerzenie sobie wymyśla np. własne funkcje obsługi błędów.

Współbieżność

Jedną z największych bolączek PHP jest brak wsparcia dla programowania współbieżnego, co uniemożliwia praktycznie tworzenie porządnych serwerów aplikacji. Do wyboru są dwa podejścia. Pierwsze to zaimplementowanie klasycznych prymitywów takich, jak klasa Thread, semafory, monitory, zmienne warunkowe i zamki. Są one powszechne, ale na dłuższą metę ciężkie w użyciu, szczególnie w większych aplikacjach. Rozwiązaniem mogłoby być wprowadzenie alternatywnego modelu współbieżności tak, jak to zrobił Erlang, gdzie mamy procesy, które przesyłają sobie komunikaty. Myślałem trochę nad erlangowym modelem, ale jest tu pewien problem: Erlang jest językiem funkcyjnym. Nie ma w nim prawdziwych zmiennych, a tym samym i efektów ubocznych, w związku z czym przesłanie obiektu w komunikacie innemu procesowi absolutnie niczym nie grozi. W językach imperatywnych na przeszkodzie stoi właśnie możliwość zmiany wartości obiektów niespodziewanej dla drugiego wątku/procesu i uszkodzenie aplikacji.

Środowisko

Aplikacje napisane w PHP mogą pracować w różnych trybach: konsola, odpowiedź na żądanie HTTP czy aplikacja okienkowa, jednak dostanie się do informacji o aktualnym środowisku uruchomieniowym jest straszliwie pomieszane. Nikt chyba nie ma wątpliwości, że obecność zmiennej $_POST, gdy aplikacja uruchomiona jest na konsoli, nie ma najmniejszego sensu. Pomimo tego taka zmienna istnieje i ma się dobrze.

Rozwiązaniem tego byłoby wprowadzenie nowego prymitywu o nazwie Environment, po którym dziedziczyłyby szczególne rodzaje środowisk. Każdy skrypt w momencie odpalenia dostawałby obiekt aktualnego środowiska, poprzez który mógłby pobrać odpowiednie dane. Oto przykładowy pseudokod dla skryptu odpalanego na dzisiejszą modłę, gdy proces obsługuje pojedyncze żądanie HTTP:

$environment = lang.getEnvironment();
if($environment instanceof HttpRequestEnv)
{
   echo 'Jestem uruchomiony jako generator odpowiedzi na żądanie HTTP. Dane POST: ';
   foreach($environment.getPost() as $name => $value)
   {
      echo $name~' => '~$value.EOL;
   }
}
if($environment instanceof ConsoleEnv)
{
   echo 'Jestem uruchomiony jako aplikacja konsolowa.';
}

Jeszcze ciekawszy przykład zastosowania to serwer aplikacji, który można odpalić jako aplikację FastCGI i podłączyć do serwera WWW. Odpalone z niego procesy mogłyby komunikować się z procesem-matką, który zarządzałby konfiguracją, połączeniami z bazą itd. dzięki czemu nie trzeba by się tym zajmować w kółko za każdym razem:

$env = lang.getEnvironment();
if(!$env instanceof FastCGIEnv)
{
   throw new EnvironmentException('Nieprawidłowe środowisko');
}
 
import appserver.Request;
 
while($message = $env->dispatchMessage())
{
   switch($message)
   {
      instanceof fastcgi.Init:
         appserver.initialize();
         break;
      instanceof fastcgi.Request:
         thread.spawn(appserver.Request.run, appserver.prepareProcessData(), $message->getRequest());
         break;
      instanceof fastcgi.Done:
         appserver.done();
   }
}

Przy okazji widzimy tu ciekawe rozszerzenie możliwości instrukcji switch, nad którym także można by się zastanowić.

Interpreter

Ostatnie propozycje to przede wszystkim wbudowany od początku odśmiecacz pamięci oraz wbudowane automatyczne kompilowanie do bajtkodu, które zrzuca obraz do pamięci lub na dysk, by nie robić tego po sto razy.

Zakończenie

Mam nadzieję, że wpis był inspirujący i zachęcił do pomyślenia nad kształtem PHP teraz i w przyszłości, a zaprezentowane tutaj kierunki rozwoju się Wam spodobały.

Powrót

Komentarze

Napisał batman w środę, 27 stycznia 2010 o 18:55

PHP jaki jest, każdy widzi. Siedzę w tym języku spory kawał czasu (z wyliczeń wychodzi mi coś koło 7 lat) i bardzo żałuję, że w ogóle go poznałem. Jestem zwolennikiem języków obiektowych (a nie zorientowanych obiektowo) oraz ze ścisłą kontrolą typów. W pewnego czasu zgłębiam tajniki C# i całej platformy .NET i żadna rewolucja w PHP nie spowoduje, że chciałbym przy tym języku zostać. Niestety developerzy PHP zapomnieli chyba o użytkownikach i za bardzo skupili się na ilości pobrań interpretera, a nie na jakości języka.

Napisał piotrooo89 w środę, 27 stycznia 2010 o 20:29

Cieszę się że powstał ten wpis, i popieram kilka Twoich propozycji. Najbardziej jestem za wywaleniem

"tekst $zmienna tekst 
, jakaś straszliwa choroba taki zapis, a co najgorsze gro ludzi z tego korzysta (nawet niekiedy ja). Co do deklaracji typów zmiennych, szczerze nie przeszkadza mi obecna deklaracja (a właściwie jej brak) choć jak będzie w przyszłości to się nie obrażę. Kolejną fajną sprawą są wyjątki, które NIE SĄ stosowane a powinny. Piszę że nie są bo tak naprawdę korzysta z nich może 20% populacji programistów PHP. Następnie poprawienie samej estetyki kody, wiadomo że dużo zależy od samego programisty ale niestety jak przyjdzie poprawiać coś po jakimś "niechluju" to naprawdę robi się mało ciekawie i nie jest już tak miło. Fajną sprawą było by jak to nazwałeś "sprzątanie" po wyjątkach, nie spotkałem się nigdy z czymś takim (pewnie dlatego że jeszcze mało na świecie widziałem) ale może to być krok milowy. Ogólnie PHP nie jest zły ale nie jest jeszcze tak zadowalający jakbyśmy tego chcieli - subiektywna opinia.

Napisał m_gol w środę, 27 stycznia 2010 o 20:33

Smalltalk jest przykładem takiego obiektowego bałaganu, o którym wspomniałeś w kontekście liczby 13. Wszystkie klasy są pośrednimi lub bezpośrednimi podklasami klasy Object, która jest podklasą klasy nil, która to klasa jest jednocześnie obiektem klasy UndefinedObject, która to klasa jest podklasą klasy... Object. W dodatku każda klasa jest obiektem klasy Class, które są jakoś włożone w klasę Metaclass i parę innych śmiesznych zależności tam jeszcze występuje. Zabawne.

Napisał stormfly w środę, 27 stycznia 2010 o 20:33

wydaje mi się, że PHP powinno zostać takie jakie jest - proste, z łatwą składnią, robienie z tego języka jako mieszanki różnych języków typu JAVA, C# wydaje mi się niepotrzebne, jeśli kogoś boli to, że PHP jest takie proste/nie spójne to właśnie powinien iść drogą batmana, wybrać inny język, rewolucji w PHP nie będzie i wydaje mi się to dobrym posunięciem, szkoda czasu i pieniędzy, jeśli ktoś widzi taką potrzebę na rynku to zawsze może napisać nowy rewolucyjny język, który będzie łączył PHP z czym dusza zapragnie ;)

Napisał piotrooo89 w środę, 27 stycznia 2010 o 21:27

@stormfly przecież nie można stać w miejscu coś się musi zmieniać. Brak zmian == regres. Ale fakt jest faktem że porównywanie PHP do JAVY lub C# jest trochę nie nie miejscu, choć PHP mógłby się "nauczyć" kilku rzeczy od tych języków.

Napisał Kocurro w czwartek, 28 stycznia 2010 o 10:03

Hmm ... tak w kwestii technicznej - przez przejściu z planety php.pl pojawia się brzydki komunikat, że hotlinkowanie jest zablokowane. Możesz zrobić wyjątek by z planety wchodziło się normalnie?

Napisał stormfly w czwartek, 28 stycznia 2010 o 10:38

@piotrooo89: PHP nie stoi w miejscu, PHP5.3 nie tak dawno wyszedł gdzie jest dużo poprawek co do obiektówki, doszły przestrzenie nazw, a niedługo wyjdzie PHP6, ale nie widzę powodu by robić jakąś większą rewolucję

Napisał Zyx w czwartek, 28 stycznia 2010 o 15:59

Kocurro -> właśnie odblokowałem planetę, już powinno być OK.

Napisał eRIZ w czwartek, 28 stycznia 2010 o 17:16

"Rozwiązaniem tego byłoby wprowadzenie nowego prymitywu o nazwie Environment"

Niby tak, ale przecież jest $_SERVER'REQUEST_METHOD'...

Napisał skynetroot w czwartek, 28 stycznia 2010 o 18:26

No ten bajzel w bibliotece standarowej to porażka. I pewnie długo tego nie poprawią ze względu na wsteczną kompatybilność.

Może zostań deweloperem PHP :)

Napisał grubas w czwartek, 28 stycznia 2010 o 19:03

quote "@piotrooo89: PHP nie stoi w miejscu, PHP5.3 nie tak dawno wyszedł gdzie jest dużo poprawek co do obiektówki, doszły przestrzenie nazw, a niedługo wyjdzie PHP6, ale nie widzę powodu by robić jakąś większą rewolucję"

Zyx ma rację "przebudować na nowo".
Projekt PHP kończy się. Teraz NIE POWINNO się dodawać nowe lub poprawiać a zastanowić się nad koncepcją rdzenia PHP tak aby był to język na kolejne lata.

Jak masz bałagan w garażu ( o ile masz garaż ) to co robisz ? przestawiasz z kąta w kąt czy układasz wszystko tak aby było cacy?

Napisał megawebmaster w czwartek, 28 stycznia 2010 o 20:49

Tutaj się nie zgodzę @stormfly. Zauważ ile głupich błędów popełniają programiści (nawet Ci zaawansowani) przez niektóre cechy PHP, dla przykładu błędy inicjacji zmiennych albo brak kontroli typów danych i nielimitowane rzutowanie. Do tego te potworne skrypty, których często używają początkujący - zgroza. Osobiście popieram pomysły Zyx'a.

Przy okazji - ile znasz hostingów na których można korzystać z PHP 5.3? A i kiedy ma być to PHP6, które jest już zapowiadane dobre kilka lat (pamiętam artykuł Zyx'a na webcity, gdzie ledwie weszło PHP 5 a już była informacja o usprawnieniach w PHP 6)

Napisał Dodek w czwartek, 28 stycznia 2010 o 21:09

Odnośnie twoich narzekań na obiektowość - myślę, że większość twoich argumentów wywodzi się z tego, że miałeś do czynienia jedynie z prymitywnymi systemami obiektowymi.

>Przypuśćmy, że integer byłby typem obiektowym?
Weźmy więc język Common Lisp, w którym liczbom można przypisać klasy.

>Jak powinienem rozumieć zapis 13? Czy jest to obiekt liczbowy z wartością "13", a może obiekt "13"?

Co to znaczy "obiekt z wartością"? W CL liczba 13 jest klasy fixnum, która jest podklasą klasy fixnum, ta jest podklasą rational, następnie są klasy real, number, t.

>Czy dwa obiekty liczbowe o wartości 13 są tym samym czy czymś innym?
W CL dwa obiekty są identyczne, jeżeli funkcja EQ wywołana z nimi jako parametrami zwróci prawdę. Standard nie specyfikuje, czy EQ dla dwóch obiektów typu number o tej samej wartości liczbowej zwróci prawdę - określa jednak funkcję =, która dla obiektów liczbowych o takiej samej wartości liczbowej musi zwrócić prawdę. Problem rozwiązany, wystarczy się umówić.

>Jeśli obiekt liczbowy, to czym jest pojęcie "wartości", skoro w języku wszystko jest obiektem?
Słowem, którego szukasz, jest "instancja".

>Obiekt powinien reprezentować byt, więc dlaczego "13" nie jest obiektem reprezentującym liczbę 13
Przede wszystkim, "13" nie jest obiektem, tylko drukowaną reprezentacją pewnego obiektu. Jak już powiedziałem, standard pozwala, żeby implementacje tworzyły "kopie" liczb, ale to żaden problem, bo kto porównuje liczby przez identyczność? Liczby porównuje się poprzez wartość liczbową.
> poprzedzonym przez obiekt "12", a następującym po "14"?
Co to znaczy, że "obiekt jest poprzedzony przez inny obiekt"?

>Jak to się ma do efektów ubocznych funkcji, kiedy obiekty kopiowane są przez referencję, a nie przez wartość?
Nijak, w CL wszystko jest przekazywane przez referencję i tak robią również chyba wszystkie nowe języki.

>I najważniejsze: na co tyle obiektów w pamięci?
Szybkie implementacje Common Lispu zasadniczo korzystają z tagów w systemie typów, dzięki czemu liczby mogą być otagowane i zajmować tylko jedno słowo pamięci, a operacje na nich mogą być niemal tak szybkie, jak w C - okupione jest to jednak pewnym zmniejszeniem maksymalnego zakresu liczb. Jednakże, dzisiaj większość procesorów jest 64-bitowa, a tag zwykle zajmuje 3-4 bajty, więc zakres ciągle jest wielki.
Lektura: http://portal.acm.org/citation.cfm?id=36205.36183 (nie wiem, czy masz dostęp do ACMu).
Jak chcesz poczytać więcej o systemie obiektowym w CL, jest taka książka na necie "Art of Metaobject Protocol" - gwarantuję, że po przeczytaniu tego niemal wszystkie inne systemy obiektowe będą ci się wydawały prymitywne.

PS. Co to za głupoty z polem "Layout" w formularzu?

Napisał BooBooGotU w czwartek, 28 stycznia 2010 o 21:56

To może też bloglines odblokujemy? Pozatym ciężko się czyta ten komunikat-krzaczki, coś nie tak z kodowaniem (Opera).

Napisał Kocurro w czwartek, 28 stycznia 2010 o 22:57

Dzięki ale chyba coś nie poszło, przed chwilą kliknąłem w link na głównej stronie php i pojawił się komunikat, musiałem ręcznie wkleić link. Przeglądarka to Chrome.

A w kwestii merytorycznej to niektóre pomysły bardzo mi się podobają, fajne by były niektóre opcje w PHP'ie.

Strona 1 z 3 :: [1] 2 3

Pamiętaj, dbaj o kulturę wypowiedzi oraz dyskusji w sieci.

Skomentuj

NickInformacja
E-mailNa wypadek potrzeby kontaktu z autorem (niepublikowany)
BlogNie zapomnij o http://
LayoutNapisz tu, czy widzisz dzienny czy nocny layout.
WpisFormatowanie wikiKomentarze są moderowane - przeczytaj zasady!

Na Zyxist.com panuje swoboda wyrażania opinii oraz krytyki pod dowolnym adresem. Jedyny warunek: musi być ona kulturalna i rzeczowa. Na chamstwo, prostactwo lub jawne obrażanie kogokolwiek nie ma tu miejsca i takie komentarze są bardzo szybko usuwane. Jeśli zamierzasz polemizować z treścią wpisu, wpierw uważnie ją przeczytaj.

© Tomasz "Zyx" Jędrzejewski 2005 - 2010 | Wykonanych zapytań: 2 | Serwer wirtualny zapewnia