Gdyby w Scali nie było "implicit", to nadal można by korzystać z tego wzorca, tylko (albo "aż") ręcznie uzupełniać "implicitParam"
Cała magia implicitów polega na tym, że to automatyczne uzupełnianie odbywa się na podstawie typu, a sam proces dopasowywania obiektu do typu może przebiegać wg dowolnego algorytmu w trakcie kompilacji (implicity są kompletne w sensie turninga, a ponadto mogą korzystać z makr). Innymi słowy, nie ma praktycznie ograniczenia na to, jak skomplikowany będzie proces znajdowania odpowiedniego obiektu. Możesz napisać sobie makro dostarczające implicit a w tym makrze 10k linii. W efekcie to "tylko" ręczne wstrzykiwanie to może być jednak bardzo duża niedogodność w porównaniu z automatycznym.
Dzięki implicitom możesz robić takie fajne rzeczy jak np. transformowanie obiektów do/z JSON bez używania refleksji.
Implicitów używa się zresztą nie tylko do wstrzykiwania, ale też do nakładania złożonych ograniczeń na typ. Przykładowo, można w Scali napisać metodę, którą da się wywołać (na etapie kompilacji) tylko dla obiektu, który nie jest określonego typu. Z każdym typem będzie działać, a z jednym wybranym nie. Zrobisz takie coś w OOP i zwykych generykach Java/C#? ;) Może przykład trochę zbyt teoretyczny, ale ogólnie mechanizm ten umiejętnie wykorzystany, pozwala programować w sposób znacznie bezpieczniejszy niż zwykłe OOP. W wielu sytuacjach bez implicitów musiałbym rzucać wyjątkami. Błąd na etapie kompilacji jest lepszy niż błąd w trakcie działania.
Kolejnym sztandarowym wręcz zastosowaniem implicitów (wraz z typami wyższych rzędów) jest realizacja metod zwracających obiekt, którego typ jest zależny od typu parametrów wejściowych. Np. transformujesz kolekcję i w wyniku chcesz dostać kolekcję tego samego typu. Spróbuj w klasycznym programowaniu obiektowym napisać uniwersalną metodę, która tworzy nową kolekcję tego samego typu, ale z inną zawartością. W praktyce mógłbyś:
- powielać implementację dla każdego typu osobno (np. osobna implementacja dla zbiorów, osobna dla list), wykorzystując przeciążanie / różne klasy
- dorzucić ręcznie jakiś parametr realizujący wzorzec "builder", ale wtedy nie wymusiłbyś na użytkowniku, że typ buildera musi odpowiadać typowi kolekcji wejściowej (tj. zapewne wymusiłbyś w runtime i sygnalizował jakimś wyjątkiem - paskudztwo).