Znane dynamicznie typy języków nigdy nie pozwalają programistom określać typów zmiennych, a przynajmniej mają bardzo ograniczone wsparcie dla tego.
Na przykład JavaScript nie zapewnia żadnego mechanizmu wymuszania typów zmiennych, gdy jest to wygodne. PHP pozwalają określić niektóre rodzaje argumentów metoda, ale nie ma sposobu, aby korzystać z rodzimych typów ( int
, string
etc.) dla argumentów i nie ma sposobu, aby wymusić typy na cokolwiek innego niż argumentów.
Jednocześnie wygodniej byłoby mieć możliwość określenia w niektórych przypadkach typu zmiennej w języku dynamicznie wpisywanym, zamiast ręcznego sprawdzania typu.
Dlaczego są takie ograniczenia? Czy to z przyczyn technicznych / wydajności (przypuszczam, że jest tak w przypadku JavaScript), czy tylko z powodów politycznych (co, jak sądzę, w przypadku PHP)? Czy dotyczy to innych dynamicznie pisanych języków, których nie znam?
Edycja: postępując zgodnie z odpowiedziami i komentarzami, oto przykład wyjaśnienia: powiedzmy, że mamy następującą metodę w zwykłym PHP:
public function CreateProduct($name, $description, $price, $quantity)
{
// Check the arguments.
if (!is_string($name)) throw new Exception('The name argument is expected to be a string.');
if (!is_string($description)) throw new Exception('The description argument is expected to be a string.');
if (!is_float($price) || is_double($price)) throw new Exception('The price argument is expected to be a float or a double.');
if (!is_int($quantity)) throw new Exception('The quantity argument is expected to be an integer.');
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Przy pewnym wysiłku można to przepisać jako (patrz także Programowanie kontraktów w PHP ):
public function CreateProduct($name, $description, $price, $quantity)
{
Component::CheckArguments(__FILE__, __LINE__, array(
'name' => array('value' => $name, 'type' => VTYPE_STRING),
'description' => array('value' => $description, 'type' => VTYPE_STRING),
'price' => array('value' => $price, 'type' => VTYPE_FLOAT_OR_DOUBLE),
'quantity' => array('value' => $quantity, 'type' => VTYPE_INT)
));
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Ale ta sama metoda zostałaby zapisana w następujący sposób, gdyby PHP opcjonalnie akceptował typy rodzime dla argumentów:
public function CreateProduct(string $name, string $description, double $price, int $quantity)
{
// Check the arguments.
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Który z nich jest krótszy do napisania? Który z nich jest łatwiejszy do odczytania?