W systemie z dynamicznym typowaniem wartości mają typy w czasie wykonywania, ale zmienne i funkcje nie. W systemie o typie statycznym zmienne i funkcje mają typy znane i sprawdzane podczas kompilacji. Np. W Pythonie xmoże być wszystko ; w czasie wykonywania, jeśli jest 1to liczba, a jeśli tak "foo", to ciąg. Będziesz wiedział tylko, który typ xbył w czasie wykonywania, i może być inny przy każdym uruchomieniu programu. W języku takim jak Java piszesz, int xjeśli xma być liczbą, i wiesz, że w czasie kompilacji xzawsze musi to być int.
Oba typy „jawne” i „niejawne” odnoszą się do systemów typu statycznego . Cechą charakterystyczną systemu statycznego jest to, że typy są znane w czasie kompilacji, ale niekoniecznie muszą być zapisane. W Javie typy są jawne - musisz je zapisać. W Javie metoda może wyglądać mniej więcej tak:
public int foo(String bar, Object baz) { ... }
Typy są znane zarówno w czasie kompilacji (statyczne), jak i zapisywane (jawne). Istnieją jednak języki, które nie zmuszają Cię do napisania tego typu. Mogą wywnioskować rodzaj funkcji na podstawie jej ciała i sposobu jej użycia. Przykładem może być OCaml, w którym możesz napisać coś takiego:
let foo x = x + 1
Odkąd +używałeś, OCaml może zorientować się, że xto intwszystko musi być samo w sobie. Tak więc typ foo( foo : int -> int) jest znany w czasie kompilacji, podobnie jak przykład Java. Jest całkowicie statyczny. Ponieważ jednak kompilator może samodzielnie ustalić, jakie typy muszą być, nie musisz sam ich zapisywać: są niejawne.
W skrócie: to, czy system typów jest jawny czy niejawny, jest własnością systemów statycznych . Jest to zupełnie inne pytanie, czy system typów jest dynamiczny czy statyczny.
Często masz systemy typów, które są czasami jawne, a czasem niejawne.
Na przykład uważam, że C # pozwala wnioskować typy za pomocą varsłowa kluczowego. Zamiast pisać int x = 10, możesz pisać, var x = 10a kompilator odkrywa, że to xmusi być int. C ++ robi coś podobnego z auto. Systemy te są zwykle jawne, ale mają pewne wnioski.
Z drugiej strony istnieją systemy, które są zwykle niejawne, ale czasami zmuszają cię do napisania podpisu typu. Haskell jest świetnym przykładem. Przez większość czasu Haskell może wnioskować o typach dla Ciebie. Czasami jednak możesz napisać dwuznaczny kod show . read, w którym Haskell nie jest w stanie samodzielnie rozróżnić typów. W tym przypadku można byłoby zmuszone do jednoznacznie określić typ albo showalbo read. Ponadto niektóre bardziej zaawansowane funkcje systemu typów (takie jak polimorfizm rangi n) powodują, że wnioskowanie jest nierozstrzygalne - to znaczy nie ma gwarancji, że się zatrzyma. Oznacza to, że kod korzystający z tej funkcji często wymaga wyraźnych podpisów typu.