Як система статичного типу впливає на дизайн мови, заснованої на прототипі?


15

Стаття Вікіпедії про мови-прототипи містить такий параграф:

Практично всі системи на основі прототипів базуються на інтерпретованих та динамічно набраних мовах. Однак системи, засновані на статично типових мовах, є технічно здійсненними.

Якими способами система статичного типу встановлює обмеження або вводить складність у мові, заснованій на прототипі, і чому існують більш динамічно набрані мови прототипів?


2
+1 та fav'd: Я досить довго обдумував це, і не знайшов надзвичайно важких проблем із системою структурного типу. Насправді це мене так сильно турбує, що я хочу випереджати і намагатись створити статично

Я сам починаю цей процес з тієї ж причини :)
Джо

Відповіді:


6

Межа між фундаментальним типом і об'єктом розмита і часто штучно введена. Наприклад, у C a структура - це лише купа записів, просто похідний не об’єктний тип. У C ++ структура - це клас із усіма полями загальнодоступними, об'єктом. Тим не менш, C ++ майже повністю назад сумісний із C ... межа тут дійсно м'яка.

Для програмування на основі прототипу потрібно мати об'єкти, що змінюються під час виконання. Вони ОБОВ'ЯЗКОВІ бути м'якими, оскільки кожна зміна під час виконання класу одного виду змінюється на інший - змінюється його тип.

Ти можеш зберегти основні та похідні не об’єктні типи як статичні. Але це вводить дивну нерівність, об'єкти м'якого типу, необ'єкти мають статичний тип, і між ними слід встановити жорсткий бар'єр. Чи зможете ви перетворити структуру? Струна? Чи повинен Число бути класом, або основним типом, або набором основних типів, int / float / bignum / тощо?

Це просто природніше і простіше в навчанні, використанні та написанні, щоб мати цю форму, всі типи є змінними або жоден тип не змінюється під час виконання. Якщо ви оголосили, що лише один тип (Об'єкт) є змінним, у вас виникають головні болі та проблеми обох світів.

Статичний тип:

  • простіше у виконанні
  • швидше / ефективніше
  • безпечніший
  • легше обслуговувати / документувати великі системи через абстракцію.

Динамічним типом є:

  • швидше писати,
  • більш стислий
  • мову легше вивчити
  • більше прощати за помилки в дизайні.

Змішуючи їх, ви багато жертвуєте.

  • Реалізація стає складнішою, ніж будь-яка з попередніх двох.
  • швидкість залежить від того, використовуєте ви м'які типи чи ні ... Якщо це так, це низько, якщо ні, то навіщо вибирати мову?
  • Безпека типу - це вікно для всіх типів об'єктів.
  • слідкувати за тим, як один тип перетворюється в інший - досить складна задача. Документувати це - дуже важко.
  • Вам потрібно все-таки вести бухгалтерію з основними типами, що вбиває стислість та швидкість написання
  • Мовна складність вища (складніше в засвоєнні), ніж будь-яка із "конкретних",
  • "пробачення" динамічного набору замінюється тенденцією до деяких дуже складних помилок при невідповідності типів атрибутів.

1
Майте на увазі приклад того, чому об’єкти потрібно "змінювати" (я припускаю, що ви маєте на увазі додавання та видалення атрибутів, не змінюючи їх, як це зазвичай не пов'язано з введенням тексту).

@delnan: не дуже, в прототипі на основі програмування ви можете копати по кишках об'єкта, як вважаєте за потрібне, видаляти, додавати, замінювати, прикривати обидва способи та атрибути в реальному екземплярі. У цьому вся суть і дуже зручна, гнучка заміна для модифікації об'єктів за допомогою жорстких правил класичного успадкування. Якщо в мові використовується клас як тип, ви не можете змінювати його структуру на льоту, якщо тип не м'який.
СФ.

1
Я не думаю, що так. За тією ж логікою можна стверджувати, що програмування на основі класу потребує тих самих свобод, як це дозволяють динамічні мови на основі класів. Ні, статичні прототипи з системами структурного типу анотуватимуть об'єкти зі списком його членів і рекурсивно їх типами, а також статично перевірять наявність цих членів (і мають правильний тип), вимагаючи, щоб усі члени були задані при створенні об'єкту або присутніх у прототип і просто не включає спосіб видалення елементів. Результат все ще виглядає для мене досить прототипним і гарантує, що кожен член присутній у всі часи.

@delnan: Ви щойно описали класичну спадщину через композицію. Так, це виглядає досить прототипно і є (дуже задумливим) способом програмування на основі прототипу в класичній мові моделі успадкування. Це лише позбавляє pb.p 90% задоволення, вбиваючи його найбільші переваги (і одночасно знімаючи найбільші небезпеки). Так, за старою аналогією для зйомки ніг повноцінний pb.p допоможе вам відстрілювати обидві ноги чайною ложкою. Якщо вам не подобається така влада, вам краще дотримуватися класичної спадщини.
СФ.

1
Ви плутаєте "динамічний" з "прототипами". Ці свободи, які не добре поєднуються із системами статичного типу, не є ознаками прототипів, вони є особливостями динамізму. Звичайно, додавання статичної типізації їм заважає, але вони не є частиною прототипів (це, в основному, IMGO не вистачає класів на користь клонування об'єктів, щоб виконувати роль батьків). Цей динамізм є ортогональним для прототипів. Усі популярні мови-прототипи включають їх, але вони не залежать від прототипів, як зазначено раніше. Розгляньте цей фрагмент вигаданою мовою: pastebin.com/9pLuAu9F . Як це не прототипи?

3

Складність досить просто зрозуміти: Вважаючи погляд на об'єкти як словники методів або як речі, які відповідають на повідомлення, дотримуйтесь наступних даних про загальноприйняті статичні типи мов OO:

  • Усі словникові ключі / повідомлення, як правило, декларуються заздалегідь, використовуючи статично оголошені ідентифікатори.

  • Певні набори повідомлень декларуються заздалегідь, а об'єкти пов'язані з цими наборами, щоб визначити, на які повідомлення вони відповідають.

  • Взаємозв'язки включення одного набору повідомлень, що є підмножиною іншого, оголошуються статично і явно; незадекларовані, але логічні підмножини недійсні.

  • Перевірка типу намагається переконатися, що всі повідомлення надсилаються лише об'єктам, які відповідають на них.

Кожен з них певною мірою конфліктує із системою, заснованою на прототипі:

  • Імена повідомлень можна оголосити заздалегідь у вигляді "атомів" чи інтернованих рядків чи чогось іншого, але мало іншого; пластичність об'єктів означає, що присвоювати типи методам незручно.

  • Можливо, суттєвою ознакою системи, заснованої на прототипі, є те, що набори повідомлень визначаються тим, на що відповідає об'єкт, а не навпаки. Було б розумно присвоювати псевдоніми певні комбінації під час компіляції, але набори повідомлень, визначені під час виконання, повинні бути можливими.

  • Справжній вплив двох вищезгаданих результатів стосується взаємозв'язків з включенням, де явні декларації є абсолютно нездійсненними. Успадкування в статичному, номінальному сенсі підтипу є антитетичним для прототипної системи.

Що призводить нас до кінцевої точки, яку ми насправді не хочемо змінювати. Ми все ще хотіли б гарантувати, що повідомлення надсилаються лише об’єктам, які відповідають на них. Однак:

  • Ми не можемо статично знати, які повідомлення можуть бути згруповані разом.
  • Ми не можемо знати, які групи є підмножинами інших.
  • Ми не можемо знати, які групи можливі.
  • Ми навіть не можемо вказати, які саме аргументи надсилаються разом з одним повідомленням.
  • В основному ми виявили, що не можемо взагалі багато нічого конкретизувати в цілком загальному випадку.

То як це можна обробити? Або обмежте повну спільність якось (що неприємно, і може швидко знищити будь-які переваги використання системи на основі прототипу в першу чергу), або зробіть тип системи набагато більш текучим і висловлюйте обмеження, а не точні типи .

Система типу на основі обмежень швидко призводить до поняття структурного підтипу , яке в дуже пухкому сенсі можна розглядати як статичний еквівалент "типи качок". Найбільші перешкоди тут полягають у тому, що такі системи набагато складніші для перевірки типу та є менш відомими (що означає, що попередня робота над вивченням).

Підсумовуючи це: Це можливо, це зробити важче, ніж або номінальну систему статичного типу, або динамічну систему, засновану на метаданих часу виконання, і тому мало хто турбується.


1

Я вважаю, що способом досягнення статично типової мови, заснованої на прототипі, було б базування мови навколо шаблонів та концепцій.

Концепції колись були запланованою особливістю для C ++ 0x. Універсальний код у шаблонах C ++ вже фактично є "статично набраним качками". Ідея концепцій полягає в тому, щоб мати можливість сказати деякі речі про необхідні члени та характеристики типів, не вимагаючи і не маючи на увазі модель успадкування класів, яка лежить в основі цього взаємозв'язку (тому що він повинен був працювати з існуючим кодом шаблону, який вже був "статично качка набрана" ).

Мовою, що ґрунтується на основі «Шаблонів та концепцій», саме Концепти будуть засновані на прототипі, і Шаблони позбавлять вас від турботи про будь-яку модель класу, яка може бути або не може використовуватися для реалізації типів значень.

Окрім хитрощів використання поетапної компіляції, щоб дозволити мові бути власною мета-мовою, ці прототипічні виводи Концепцій обов'язково були б незмінними, коли вони будуть створені. Однак заперечення про те, що це не прототип, - це червона оселедець. Це була б просто функціональна мова. Динамічний прототип бази мови , який також є функціональним має , по крайней мере , була зроблена спроба .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.