Początkowo programista musiał zapisać program w kodzie maszynowym. Później powstały języki symboliczne, asemblery oraz kompilatory, które tłumaczyły kod źródłowy programu na kod maszynowy komputera. Późniejsze maszyny były tworzone wraz z bibliotekami, które zawierały ułatwiający pracę gotowy kod zapisany na kartach perforowanych lub taśmach magnetycznych. Takie biblioteki były następnie łączone z programem użytkownika i pomagały w typowych operacjach, np. wejścia i wyjścia. Z nich wywodzą się nowoczesne systemy operacyjne.
Wraz ze wzrostem mocy obliczeniowej komputerów czas pracy poszczególnych programów malał, przez co stosunek czasu, w którym jeden użytkownik kończył pracę i przekazywał sprzęt następnemu, do czasu pracy programów rósł bardzo szybko. Rozliczanie pracy użytkowników na maszynach ewoluowało z ręcznego sprawdzania zegara do automatycznego logowania przez sam komputer. Kolejki zmieniły się z dosłownej kolejki ludzi czekających przy drzwiach na stos nośników leżących na stole z oczekującymi zadaniami albo stos kart perforowanych leżących na czytniku, z którego komputery same potrafiły wybierać następne karty. Wyznaczeni operatorzy przejęli obowiązki programistów uruchamiania programów na komputerze, a także utrzymywania maszyny w dobrym stanie technicznym.