(Бұл – 2001 жылғы 10 мамырда MIT-де өткен бағдарламалау тілдерінің дизайны туралы панельдік пікірталасқа арнап жазған кейбір жазбаларым.)
1. Бағдарламалау тілдері адамдарға арналған.
Бағдарламалау тілдері – адамдардың компьютерлермен сөйлесу тәсілі. Бірмәнді әрі түсінікті болса болғаны, компьютер кез келген тілде сөйлесуге қуана келісер еді. Бізде жоғары деңгейлі тілдердің болуының себебі – адамдардың машиналық тілді көтере алмайтындығында. Бағдарламалау тілдерінің мәні – біздің бейшара, әлсіз адамдық миымызды қаптаған ұсақ-түйек детальдардың басып қалуынан сақтау.
Сәулетшілер дизайн мәселелерінің кейбір түрлері басқаларына қарағанда адамға көбірек байланысты екенін біледі. Ең таза, ең дерексіз дизайн мәселелерінің бірі – көпірлерді жобалау. Онда сіздің міндетіңіз негізінен ең аз материал жұмсап, берілген қашықтықты жалғау болып табылады. Ал оның екінші шетінде орындықтарды жобалау тұр. Орындық дизайнерлері өз уақытын адамның бөксесі туралы ойланумен өткізуге мәжбүр.
Бағдарламалық жасақтама да дәл осылай бөлінеді. Деректерді желі арқылы бағыттау алгоритмдерін жобалау – көпір салу сияқты тамаша, дерексіз мәселе. Ал бағдарламалау тілдерін жобалау орындық жасау сияқты: мұндағы басты мәселе – адамның әлсіздіктерімен жұмыс істеу.
Көбіміз мұны мойындағымыз келмейді. Адамның әлсіздіктеріне бейімделуден гөрі, зор математикалық талғампаздыққа толы жүйелерді жасау көбімізге әлдеқайда тартымдырақ көрінеді. Математикалық талғампаздықтың да өз орны бар: кейбір талғампаздық түрлері бағдарламаларды түсінуді жеңілдетеді. Бірақ талғампаздықтың өзі түпкі мақсат емес.
Тілдер адамның әлсіздіктеріне сәйкес жасалуы керек дегенде, мен тілдер нашар бағдарламашыларға арналып жасалуы керек деп тұрған жоқпын. Шын мәнінде, меніңше, сіз тілді ең мықты бағдарламашыларға арнап жасауыңыз керек, бірақ тіпті ең мықты бағдарламашылардың да шектеулері бар. Барлық айнымалылары бүтін санды индексі бар x әрпінен тұратын тілде бағдарлама жазу ешкімге де ұнай қоймас.
2. Өзіңіз және достарыңыз үшін жасаңыз.
Егер сіз бағдарламалау тілдерінің тарихына көз жүгіртсеңіз, ең үздік тілдердің көбі авторларының өздері қолдануы үшін жасалған, ал ең нашарларының көбі басқа адамдар қолдануы үшін жасалған.
Тілдер басқа адамдар үшін жасалған кезде, ол әрқашан белгілі бір нақты адамдар тобына арналады: тіл дизайнері сияқты ақылды емес адамдарға. Нәтижесінде сізге жоғарыдан төмен қарайтын тіл пайда болады. Cobol – бұған ең айқын мысал, бірақ бұл рух өте көптеген тілдерге сіңіп кеткен.
Мұның тілдің қаншалықты абстрактілі екеніне еш қатысы жоқ. C тілі айтарлықтай төмен деңгейлі, бірақ ол өз авторларының пайдалануы үшін жасалған, міне хакерлердің оны жақсы көретін себебі де осында.
Тілдерді нашар бағдарламашылар үшін жасау керек деген уәж мынаған сүйенеді: жақсы бағдарламашыларға қарағанда нашар бағдарламашылар көп. Бұл солай да шығар. Бірақ сол аз ғана жақсы бағдарламашылар бүкіл бағдарламалық жасақтаманың пропорционалды түрде тым үлкен бөлігін жазады.
Мені мына сұрақ қызықтырады: ең үздік хакерлерге ұнайтын тілді қалай жасауға болады? Менің ойымша, бұл сұрақ «жақсы бағдарламалау тілін қалай жасауға болады?» деген сұрақпен бірдей, бірақ олай болмаған күннің өзінде, бұл кем дегенде өте қызықты сұрақ.
3. Бағдарламашыға барынша көп бақылау беріңіз.
Көптеген тілдер (әсіресе басқа адамдарға арналып жасалғандары) тәрбиеші әйел сияқты әрекет етеді: олар өздерінің ойынша сізге пайдалы емес нәрселерді істеуіңізге кедергі жасауға тырысады. Маған керісінше тәсіл ұнайды: бағдарламашыға мүмкіндігінше көп бақылау беріңіз.
Мен Lisp-ті алғаш үйренгенімде, оның маған ең қатты ұнағаны – мені тең құқылы серіктес ретінде қабылдағаны болды. Оған дейін мен үйренген басқа тілдерде тіл бар болатын және сол тілде жазылған менің бағдарламам бар еді, әрі бұл екеуі бір-бірінен мүлдем бөлек тұратын. Ал Lisp-те мен жазған функциялар мен макростар тілдің өзін құрайтындармен бірдей болды. Қаласам, тілдің өзін қайта жазып шыға алар едім. Оның ашық бастапқы кодты бағдарламалық жасақтама сияқты тартымдылығы бар еді.
4. Ықшамдылыққа ұмтылыңыз.
Ықшамдылық бағаланбайды, тіпті оған менсінбей қарайды. Бірақ хакерлердің жүрегіне үңілсеңіз, олардың мұны шынымен жақсы көретінін көресіз. Мысалы, APL-де бар болғаны бірнеше жол кодпен таңғажайып нәрселер жасай алатыны туралы хакерлердің тамсана айтқанын қанша рет естідіңіз? Меніңше, шынымен ақылды адамдар шын жүректен жақсы көретін кез келген нәрсеге көңіл бөлген жөн.
Бағдарламаларды қысқарту үшін жасай алатын кез келген дерлік әрекетіңіз жақсы нәтиже береді деп ойлаймын. Кітапханалық функциялар көп болуы керек; жасырын (implicit) қалдыруға болатын кез келген нәрсе солай болуы тиіс; синтаксис барынша ықшам болуы керек; тіпті атаулардың өзі қысқа болуы қажет.
Және тек бағдарламалар ғана қысқа болмауы керек. Нұсқаулық та жұқа болуы тиіс. Нұсқаулықтардың көп бөлігі түсіндірулер мен ескертпелерді, қауіп туралы ескертулерді және ерекше жағдайларды қамтиды. Егер сіз өзіңізді нұсқаулықты қысқартуға мәжбүрлесеңіз, ең жақсы жағдайда мұны тілдегі соншалықты көп түсіндіруді қажет еткен кемшіліктерді түзету арқылы жасайсыз.
5. Хакерліктің не екенін мойындаңыз.
Көптеген адамдар хакерліктің математика немесе кем дегенде жаратылыстану ғылымына ұқсас бірдеңе болғанын қалайды. Меніңше, хакерлік көбірек сәулет өнеріне ұқсайды. Сәулет өнері физикамен байланысты, яғни сәулетшілер құлап қалмайтын ғимараттарды жобалауы керек, бірақ сәулетшілердің нақты мақсаты – статика саласында жаңалықтар ашу емес, керемет ғимараттар салу.
Хакерлердің айналысқысы келетін ісі – тамаша бағдарламалар жасау. Және, кем дегенде, өз санамызда біз тамаша бағдарламалар жазу мақтауға тұрарлық іс екенін есте ұстауымыз керек, тіпті бұл еңбек ғылыми мақалалардың дәстүрлі зияткерлік құндылығына оңай айнала қоймаса да. Зияткерлік тұрғыдан алғанда, ғылыми мақала жариялауға болатын қандай да бір идеяны бейнелейтін сұмдық тіл жасағаннан гөрі, бағдарламашылар жақсы көретін тілді жобалау дәл сондай құнды іс.
1. Үлкен кітапханаларды қалай ұйымдастыруға болады?
Кітапханалар бағдарламалау тілдерінің барған сайын маңызды құрамдас бөлігіне айналып келеді. Олар сонымен қатар көлемі жағынан да үлкейіп келеді, ал бұл қауіпті болуы мүмкін. Егер сізге қажет нәрсені істейтін кітапханалық функцияны табуға оны өзіңіз жазып шығудан гөрі көбірек уақыт кетсе, онда бұл кодтың барлығы сіздің нұсқаулығыңызды қалыңдатудан басқа ештеңе бітірмейді. (Symbolics нұсқаулықтары бұған нақты мысал болды.) Сондықтан біз кітапханаларды ұйымдастыру тәсілдерімен жұмыс істеуіміз керек деп ойлаймын. Ең дұрысы, бағдарламашы қай кітапханалық шақыру дұрыс нәтиже беретінін өзі сезіп, таба алатындай етіп жобалау болар еді.
2. Адамдар шынымен префикстік синтаксистен қорқа ма?
Бұл – ашық мәселе, өйткені мен бұл туралы көп жылдар бойы ойланып келемін және әлі күнге дейін жауабын білмеймін. Префикстік синтаксис маған өте табиғи болып көрінеді, тек математиканы қоспағанда. Бірақ Lisp-тің кең таралмауының көп бөлігі жай ғана үйреншіксіз синтаксиске байланысты болуы мүмкін. Егер бұл рас болса, бұған қатысты бірдеңе істеу керек пе, жоқ па – бұл бөлек сұрақ.
3. Серверге негізделген бағдарламалық жасақтама үшін не қажет?
Менің ойымша, алдағы жиырма жылда жазылатын ең қызықты жаңа қосымшалардың көбі вебке негізделген қосымшалар, яғни серверде отыратын және сізбен веб-шолғыш арқылы байланысатын бағдарламалар болады. Ал мұндай бағдарламаларды жазу үшін бізге кейбір жаңа нәрселер қажет болуы мүмкін.
Бізге қажет нәрселердің бірі – серверге негізделген қосымшалардың шығарылуының (релизінің) жаңа тәсілін қолдау. Жұмыс үстелі (desktop) бағдарламалық жасақтамасы сияқты жылына бір немесе екі үлкен релиз жасаудың орнына, серверге негізделген қолданбалар шағын өзгерістер тізбегі ретінде шығарылады. Сізде күніне бес немесе он ретке дейін релиз болуы мүмкін. Және әдетте, бәрі әрқашан ең соңғы нұсқаны пайдаланатын болады.
Бағдарламаларды жөндеуге (дебагтауға) ыңғайлы етіп жобалауға болатынын білесіз ғой? Сол сияқты серверге негізделген бағдарламалық жасақтама да өзгертілуге оңай етіп жобалануы керек. Сіз оны оңай өзгерте алуыңыз керек немесе кем дегенде ненің кішігірім өзгеріс, ал ненің маңызды өзгеріс екенін білуіңіз қажет.
Серверге негізделген бағдарламалық жасақтама үшін таңқаларлықтай пайдалы болып шығуы мүмкін тағы бір нәрсе – continuation-дар. Вебке негізделген бағдарламалық жасақтамада сіз веб-сессияның табиғатынан күйсіз (stateless) әлемінде қосалқы бағдарламалардың (subroutine) әсерін алу үшін continuation-passing стиліне ұқсас нәрсені пайдалана аласыз. Егер тым қымбатқа түспесе, нақты continuation-дардың болғаны құнды болар еді.
4. Ашылмаған қандай жаңа абстракциялар қалды?
Бұл қаншалықты орынды үміт екенін білмеймін, бірақ жеке өзім шын мәнінде жаңа абстракция ашқым келеді – бірінші класты функциялар немесе рекурсия, не тіпті кілттік сөз параметрлері сияқты үлкен өзгеріс әкелетін бірдеңе. Бұл қол жетпес арман болуы мүмкін. Мұндай нәрселер жиі ашыла бермейді. Бірақ мен әрқашан ізденістемін.
1. Сіз қалаған кез келген тілді пайдалана аласыз.
Бұрын қолданбалы бағдарламалар жазу десктоптық бағдарламалық жасақтама жазуды білдіретін. Ал десктоптық бағдарламалық жасақтамада қолданбаны операциялық жүйемен бірдей тілде жазуға деген үлкен бейімділік бар. Сондықтан осыдан он жыл бұрын бағдарламалық жасақтама жазу көбінесе C тілінде бағдарлама жазуды білдірді. Ақырында бір дәстүр қалыптасты: қолданбалы бағдарламалар ерекше тілдерде жазылмауы керек. Және бұл дәстүрдің дамығаны сонша, менеджерлер мен венчурлік инвесторлар сияқты техникалық емес адамдар да мұны қағида ретінде қабылдады.
Серверге негізделген бағдарламалық жасақтама бұл бүкіл модельдің күлін көкке ұшырады. Серверге негізделген бағдарламалық жасақтамамен сіз өзіңіз қалаған кез келген тілді пайдалана аласыз. Мұны әлі күнге дейін ешкім дерлік түсінбейді (әсіресе менеджерлер мен венчурлік инвесторлар). Мұны бірнеше хакер ғана түсінеді, сондықтан да біз Perl және Python сияқты жаңа, тәуелсіз тілдер туралы естіп жатырмыз. Біз Perl және Python туралы адамдар оларды Windows қосымшаларын жазу үшін пайдаланып жатқандықтан естіп отырған жоқпыз.
Бағдарламалау тілдерін жобалауға қызығушылық танытатын біз үшін бұл – біздің жұмысымыздың енді нақты аудиториясы пайда болуы мүмкін дегенді білдіреді.
2. Жылдамдық профилировщиктерден келеді.
Тіл дизайнерлері, немесе кем дегенде тілді жүзеге асырушылар, жылдам код жасайтын компиляторлар жазғанды ұнатады. Бірақ меніңше, бұл тілдерді пайдаланушылар үшін жылдам ететін нәрсе емес. Knuth әлдеқашан жылдамдық тек бірнеше маңызды тар жерлерде (bottlenecks) ғана мәнге ие болатынын көрсеткен. Және мұны байқап көрген кез келген адам бұл тар жерлердің қайда екенін алдын ала болжай алмайтыныңызды біледі. Мұның жауабы – профилировщиктер.
Тіл дизайнерлері дұрыс емес мәселені шешіп жатыр. Пайдаланушыларға жылдам жұмыс істейтін бенчмарктер қажет емес. Оларға өз бағдарламаларының қай бөліктерін қайта жазу керектігін көрсете алатын тіл қажет. Тәжірибеде жылдамдық осыдан келеді. Сондықтан тілді жүзеге асырушылар компиляторды оңтайландыруға жұмсайтын уақытының жартысын жақсы профилировщик жазуға жұмсаса, бұл сөзсіз ұтыс болар еді.
3. Тілдің дизайнын алға жетелеу үшін сізге нақты қосымша қажет.
Бұл абсолютті ереже болмауы мүмкін, бірақ ең жақсы тілдердің барлығы олар арқылы жазылған қандай да бір нақты қолданбамен бірге дамыған сияқты. C тілін жүйелік бағдарламалау үшін қажет еткен адамдар жазды. Lisp ішінара символдық дифференциалдау үшін әзірленді және McCarthy-дің іске кірісуге асыққаны соншалық, ол 1960 жылғы Lisp туралы алғашқы мақаласында-ақ дифференциалдау бағдарламаларын жазып жүрді.
Егер сіздің қолданбаңыз қандай да бір жаңа мәселені шешетін болса, тіпті жақсы. Бұл сіздің тіліңізді бағдарламашыларға қажет жаңа мүмкіндіктерге ие болуға итермелейді. Жеке өзім серверге негізделген қосымшаларды жазуға қолайлы болатын тіл жазуға қызығамын.
[Панельдік талқылау кезінде Guy Steele де осы мәселені көтерді, оған қоса тіліңіз компиляторлар жазуға арналмаған болса, бұл қолданба сіздің тіліңізге компилятор жазудан тұрмауы керек деген ұсыныс айтты.]
4. Тіл бір реттік бағдарламаларды жазуға ыңғайлы болуы керек.
Бір реттік бағдарламаның не екенін білесіз: қандай да бір шектеулі тапсырма үшін тез арада жаза салатын нәрсе. Менің ойымша, егер жан-жағыңызға қарасаңыз, көптеген үлкен, байыпты бағдарламалардың бір реттік бағдарлама ретінде басталғанын көрер едіңіз. Мен көптеген бағдарламалар бір реттік бағдарлама ретінде басталды десе, таңғалмас едім. Сондықтан, егер сіз жалпы бағдарламалық жасақтаманы жазуға жақсы тіл жасағыңыз келсе, ол бір реттік бағдарламаларды жазуға жақсы болуы керек, өйткені бұл – көптеген бағдарламалық жасақтаманың дернәсілдік кезеңі.
5. Синтаксис семантикамен байланысты.
Синтаксис пен семантиканы бір-бірінен мүлдем бөлек деп қарастыру дәстүрге айналған. Бұл таңқаларлық естілуі мүмкін, бірақ олар бір-бірінен бөлек болмауы да ғажап емес. Менің ойымша, тіліңізде нені қалайтыныңыз оны қалай өрнектейтініңізбен байланысты болуы мүмкін.
Жақында мен Robert Morris-пен сөйлескен едім, ол инфикстік синтаксисі бар тілдерде операторларды қайта анықтау (overloading) үлкен ұтыс беретінін атап өтті. Префикстік синтаксисі бар тілде сіз анықтаған кез келген функция шын мәнінде оператор болып табылады. Егер сіз өзіңіз ойлап тапқан жаңа сан түрі үшін қосуды анықтағыңыз келсе, оларды қосатын жаңа функцияны анықтай саласыз. Егер мұны инфикстік синтаксисі бар тілде жасасаңыз, қайта анықталған операторды пайдалану мен функцияны шақырудың арасында сыртқы түрі жағынан үлкен айырмашылық болады.
1. Жаңа бағдарламалау тілдері.
1970 жылдары жаңа бағдарламалау тілдерін жобалау сәнде болды. Соңғы кездері олай болмай қалды. Бірақ мен серверге негізделген бағдарламалық жасақтама жаңа тілдерді қайтадан сәнге айналдырады деп ойлаймын. Серверге негізделген бағдарламалық жасақтаманың арқасында сіз өзіңіз қалаған кез келген тілді пайдалана аласыз, сондықтан егер біреу шынымен қолданыстағылардан жақсырақ көрінетін тіл жасаса, тәуекелге бел буып, оны қолданатын адамдар табылады.
2. Уақытты бөлу (Time-Sharing).
Richard Kelsey өткен панельде мұны уақыты қайта келген идея ретінде ұсынды, мен онымен толықтай келісемін. Менің болжамымша (және Microsoft-тың да болжамы бойынша), көптеген есептеулер жұмыс үстелінен қашықтағы серверлерге көшеді. Басқаша айтқанда, time-sharing қайта оралды. Және меніңше, бұған тіл деңгейінде қолдау қажет болады. Мысалы, Richard пен Jonathan Rees-тің Scheme 48 аясында процестерді жоспарлауды (process scheduling) жүзеге асыру бойынша көп жұмыс істегенін білемін.
3. Тиімділік.
Жақында компьютерлер ақыры жеткілікті деңгейде жылдам болғандай көріне бастады. Байт-код туралы барған сайын көбірек ести бастадық, бұл кем дегенде маған бізде бос процессор циклдері жетерлік дегенді білдіретіндей көрінеді. Бірақ серверге негізделген бағдарламалық жасақтамамен бізде ондай молшылық болмайды деп ойлаймын. Бағдарламалық жасақтама жұмыс істейтін серверлер үшін біреу төлеуі керек болады және олардың бір машинада қанша пайдаланушыға қызмет көрсете алатындығы олардың күрделі шығындарының бөлгіші болады.
Сондықтан тиімділік кем дегенде есептеу тар жерлерінде маңызды болады деп ойлаймын. Әсіресе енгізу/шығару (i/o) амалдарын жылдам орындау өте маңызды болады, өйткені серверге негізделген қосымшалар өте көп енгізу/шығару операцияларын жасайды.
Сайып келгенде, байт-кодтың тиімсіз болып шығуы да мүмкін. Sun және Microsoft қазіргі уақытта байт-кодтар шайқасына түсіп жатқандай көрінеді. Бірақ олар мұны байт-кодтың өзі жақсы идея болғандықтан емес, процеске өздерін енгізудің ыңғайлы нүктесі болғандықтан жасап отыр. Бұл бүкіл шайқас алаңының айналып өтілуі де әбден мүмкін. Бұл өте қызық болар еді.
1. Клиенттер.
Бұл жай ғана болжам, бірақ менің ойымша, көптеген қосымшалар үшін ұтымды модель таза серверге негізделген модель болады. Әркімнің қолында сіздің клиенттік қосымшаңыз болады деген болжаммен бағдарлама жасау – әркім адал болады деген болжаммен қоғам құрумен бірдей. Бұл сөзсіз ыңғайлы болар еді, бірақ мұндай ешқашан болмайды деп есептеуіңіз керек.
Менің ойымша, вебке қандай да бір қолжетімділігі бар құрылғылар күрт көбейеді және олар туралы бар болжамыңыз олардың қарапайым html мен пішіндерді (forms) қолдай алатыны ғана болады. Ұялы телефоныңызда браузер бола ма? Palm pilot-ыңызда телефон бола ма? Blackberry-іңіздің экраны үлкейе ме? Gameboy-ыңызда вебті қарай аласыз ба? Сағатыңызда ше? Мен білмеймін. Егер мен бәрі жай ғана серверде болады деп бәс тіксем, мұны білуімнің қажеті де жоқ. Барлық миды серверде ұстау әлдеқайда сенімдірек.
2. Объектіге бағытталған бағдарламалау.
Бұл пікірталас тудыратын мәселе екенін түсінемін, бірақ менің ойымша, объектіге бағытталған бағдарламалау соншалықты керемет нәрсе емес. Меніңше, бұл терезелік жүйелер, симуляциялар және CAD бағдарламалары сияқты деректер құрылымының дәл осы түрін қажет ететін қолданбалардың белгілі бір түрлері үшін жақсы модель. Бірақ неліктен ол бүкіл бағдарламалаудың моделі болуы керек екенін түсінбеймін.
Үлкен компаниялардағы адамдардың объектіге бағытталған бағдарламалауды ұнататын себебінің бір бөлігі – ол сырт көзге нағыз жұмыс болып көрінетін нәрсені көп тудыратындығында деп ойлаймын. Әдетте бүтін сандар тізімі ретінде табиғи түрде көрсетілуі мүмкін нәрсе енді қаптаған қаңқаларымен, қарбаласымен және әбігерімен бірге класс ретінде көрсетіле алады.
Объектіге бағытталған бағдарламалаудың тағы бір тартымдылығы – әдістер (methods) сізге бірінші класты функциялардың кейбір әсерлерін береді. Бірақ бұл Lisp бағдарламашылары үшін ескі жаңалық. Сізде нақты бірінші класты функциялар болған кезде, бәрін кластар мен әдістердің қалыбына тықпаламай-ақ, оларды алдыңыздағы міндетке қалай сәйкес келсе, солай қолдана аласыз.
Тіл дизайны үшін бұл нені білдіреді десеңіз, меніңше, объектіге бағытталған бағдарламалауды тілге тым терең сіңірмеу керек. Мүмкін, бұған шешім – жалпылама, базалық механизмдерді ұсынып, адамдарға кітапхана ретінде өздері қалаған кез келген объектілік жүйелерді жобалауға мүмкіндік беру шығар.
3. Комитетпен жобалау.
Тіліңізді комитеттің жобалауы – үлкен қателік, және бұл тек бәрі білетін себептерге ғана байланысты емес. Комитеттердің бұдыр, бірізді емес дизайндар шығаруға бейім екенін бәрі біледі. Бірақ менің ойымша, бұдан да үлкен қауіп – олардың тәуекелге бармайтындығында. Тек бір адам жауапты болған кезде, ол комитет ешқашан келіспейтін тәуекелдерге бара алады.
Дегенмен, жақсы тіл жасау үшін тәуекелге бару қажет пе? Көптеген адамдар тіл дизайны – бұл қалыптасқан жалпы пікірге мейлінше жақын болуды талап ететін сала деп ойлауы мүмкін. Мен бұлай емес екеніне бәс тігуге дайынмын. Адамдар жасайтын басқа барлық нәрселерде табыс тәуекелге пропорционалды. Тіл дизайны неге басқаша болуы керек?