(Niektóre z moich uwag zostały już wspomniane w innych odpowiedziach, ale czuję, że zapewniam wystarczająco inną perspektywę, aby uczynić tę wartość bardziej wartą odpowiedzi niż komentarza.)
Zanim zajmiemy się kwestią, czy specyfikacja może być naprawdę i całkowicie jednoznaczna, musimy odpowiedzieć na pytanie, czy powinna być jednoznaczna, przynajmniej na poziomie, o który pytasz.
Podejdę do tego z perspektywy menedżera programu pracującego nad małym lub średnim projektem lub funkcji w ramach większego projektu. Zazwyczaj istnieją dwa różne typy specyfikacji, które zostaną napisane dla takiego projektu: specyfikacja funkcjonalna (lub PM) i specyfikacja projektowa (lub Dev):
- Specyfikacja funkcjonalna ma za zadanie opisanie, co powinna zrobić projekcja lub funkcja, często z perspektywy klienta. Zasadniczo nie powinien opisywać, jak należy to zrobić. W zależności od rodzaju projektu klientowi może zależeć, jak wygląda zewnętrzny interfejs API, ale czy klientowi zależy, czy klasa A dziedziczy po klasie B, czy implementuje interfejs C? Nie powinien. I specyfikacja funkcjonalna również nie powinna. To już wprowadza jeden poziom dwuznaczności: poziom techniczny.
- Specyfikacja projektu ma na celu opisanie, w jaki sposób należy spełnić wymagania funkcjonalne, z perspektywy architekta lub projektanta technicznego elementu lub projektu. Ma on na celu rozwiązanie dwuznaczności projektu technicznego na wysokim poziomie. Będzie zawierał te szczegóły, których nie chciałeś w specyfikacji funkcjonalnej, takie jak architektura rozwiązania, w tym struktura klas, dziedziczenie, być może nawet poszczególne funkcje i metody, w zależności od zakresu i skali projektu. Czy architekt dba o to, co nazywamy zmiennymi tymczasowymi, czy też używasz listy lub tablicy dla wewnętrznego typu danych? Zakładając, że ufa programistom, nie powinna, podobnie jak specyfikacja projektu. Wprowadza to drugi poziom niejednoznaczności: poziom implementacji.
Zasadniczo te szczegóły na poziomie implementacji nie są ujmowane w formalnym dokumencie, ale same w sobie dokumentowane w samym kodzie, w tym w komentarzach. Ten poziom niejednoznaczności pozwala dobremu programistowi na wykorzystanie własnych umiejętności i podejmowanie szczegółowych decyzji technicznych, które są znakiem rozpoznawczym dobrego indywidualnego programisty. Z tego powodu nie zawaham się powiedzieć, że dwuznaczność w specyfikacji jest w rzeczywistości dobrą rzeczą: pozwala programistom wykonywać swoje zadania i podnosi ich ponad zwykłe „małpy kodowe”.
Nie oznacza to jednak, że cały dokument powinien być niejednoznaczny. Na wysokim poziomie nie powinno być wątpliwości co do interfejsu z klientem. Jeśli funkcja ma publiczny interfejs API, należy ją ściśle zdefiniować. Jeśli system wymaga podania daty, aby wykonać swoje zadanie, to czy data ta powinna być w lokalnej strefie czasowej czy w UTC? Jaki format jest potrzebny? Czy musi być dokładny do milisekundy, czy minuta jest w porządku?
Wracając do pytania, czy można użyć języka naturalnego do stworzenia jednoznacznych specyfikacji, to prawda, że nie jest on zbyt dobry w uchwyceniu tego poziomu jasności. Widziałem to w pewnych ograniczonych okolicznościach, ale są to prawdopodobnie wyjątkowe wyjątki, których nie możemy zastosować uniwersalnie. Najczęściej niejasności rozwiązuje się za pomocą technicznego żargonu, diagramów, a nawet pseudokodu. Gdy zaczniesz korzystać z pomocy takich narzędzi, język naturalny przestaje być jedynym deskryptorem. Ponieważ narzędzia te mogą uczynić nawet całkowicie funkcjonalnie jednoznaczną specyfikację o wiele bardziej wyraźną, zaryzykowałbym stwierdzenie, że nie należy nawet podejmować takiego przedsięwzięcia.
To powiedziawszy, ponieważ język naturalny jest ogólnie uzupełniany przez te narzędzia, aby uczynić go jednoznacznym funkcjonalnie, moim profesjonalnym zdaniem jest to, że żaden język naturalny nie jest wystarczający do stworzenia jednoznacznych specyfikacji we wszystkich przypadkach.