Типи в Lisp і Scheme


10

Тепер я бачу, що у Ракетки є типи. На перший погляд це здається майже ідентичним типізації Haskell. Але чи CLOS Lisp охоплює частину космічного типу Haskell? Створення дуже суворого типу Haskell і об'єкта будь-якою мовою ОО видається нечітко схожим. Просто я випив якусь частину допомоги Haskell, і я абсолютно параноїчний, що якщо я спускаюсь по Ліспській дорозі, я буду вкручений через динамічне набирання тексту.

Відповіді:


6

Система типу CL є більш виразною, ніж система Haskell, наприклад, ви можете мати тип (or (integer 1 10) (integer 20 30))для значення 1,2,...9,10,20,21,...,30.

Однак компілятори Lisp не змушують їх розуміти безпеку типу в горлі, тому ви можете ігнорувати їх "замітки" - на свій страх і ризик .

Це означає, що ви можете написати Haskell в Lisp (так би мовити), оголосивши всі типи значень і ретельно переконавшись, що всі необхідні типи зроблені, але тоді простіше використовувати Haskell в першу чергу.

Якщо ви хочете сильно статично вводити текст, використовуйте Haskell або OCaml, якщо ви хочете сильно динамічно вводити текст, використовуйте Lisp. Якщо ви хочете слабко статично вводити текст, використовуйте C, якщо вам потрібно слабке динамічне введення тексту, використовуйте Perl / Python. Кожен шлях має свої переваги (і завзяття) та недоліки (і недоброзичливці), тож ви отримаєте користь від вивчення всіх них.


19
Кожен, хто використовує такі терміни, як "примусити безпеку в горлі", не розуміє, що таке безпека типу або чому це корисно.
Мейсон Уілер

11
@MasonWheeler: той, хто зробить чудовий висновок з однієї фрази, буде помилятися частіше, ніж інакше. Як, наприклад, у цьому випадку.
sds

4
Оскільки тема є мовами, термін "вниз за горлом" є відповідним і влучним образом.
luser droog

1
@KChaloux: Я мав на увазі "виразний", як пояснено на прикладі.
sds

4
Ви все отримали назад. Динамічне введення тексту - особливий випадок статичного набору тексту, коли ви змушуєте програміста використовувати 1 тип для всього. Я можу зробити те ж саме (дослівно) у більшості мов, що мають статичний тип, оголошуючи кожну змінну як тип Objectабо будь-який корінь дерева типу. Це менш виразні, тому що ви позбавлені від варіанту сказати , що деякі змінні можуть містити тільки певні значення.
Доваль

5

Набрана ракетка сильно відрізняється від Haskell. Системи типів в Lisp і Scheme, і взагалі типові системи в традиційно нетипових мовних екосистемах взагалі, мають фундаментальну мету, яку інші системи типів не мають - взаємодіяти з існуючим нетипізованим кодом . Наприклад, типізована ракетка запровадила цілі нові правила набору тексту, щоб вмістити різні ідіоми ракетки. Розглянемо цю функцію:

(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Для порожніх списків це повертає перший елемент. Для порожніх списків це повертає помилкове значення. Це часто зустрічається в нетипізованих мовах; набрана мова використовує певний тип обгортки, Maybeабо видасть помилку в порожньому регістрі. Якщо ми хотіли додати тип до цієї функції, який тип слід використовувати? Це не так [a] -> a(у позначенні Haskell), тому що може повернути помилкове. Це також немає [a] -> Either a Boolean, тому що (1) він завжди повертає помилку в порожньому регістрі, а не довільне булеве значення, а (2) тип "Either" буде вбудовувати елементи в Leftfalse та false Rightі вимагати, щоб ви "розгорнули будь-яке", щоб дійти до фактичного елемента. Натомість значення повертає справжній союз- немає конструкторів для обгортки, він просто повертає один тип в деяких випадках, а інший - в інших випадках. У набраній ракетці це представлено конструктором типу об'єднання:

(: first (All (A) (-> (Listof A) (U A #f))))
(define (first some-list)
  (if (empty? some-list)
      #f
      (car some-list)))

Тип (U A #f)станів, функція може повертати або елемент списку, або false без жодного Eitherекземпляра обгортки . Засіб перевірки типів може зробити висновок, що some-listце або тип, (Pair A (Listof A))або порожній список, і, крім того, він робить висновок, що в двох гілках оператора if відомо, що з них є випадком . Програма перевірки типів знає, що у (car some-list)виразі список повинен мати тип, (Pair A (Listof A))оскільки умова if це забезпечує. Це називається типізацією явищ і покликане полегшити перехід від нетипізованого коду до введеного коду.

Проблема - міграція. Там є безліч нетипізованих кодів ракетки, і набрана ракетка не може просто змусити вас відмовитися від усіх улюблених типових бібліотек і витратити місяць, додаючи типи до вашої кодової бази, якщо ви хочете її використовувати. Ця проблема застосовується кожного разу, коли додавання типів поступово до існуючої бази коду, див. TypeScript та його будь-який тип для застосування javascript цих ідей.

Система поступового типу повинна забезпечувати інструменти для роботи із загальними нетипізованими ідіомами та взаємодії з існуючим нетипізованим кодом. Використовувати його буде досить болісно, ​​інакше див. "Чому ми більше не використовуємо Core.typed" для прикладу Clojure.


1
В економіці це відоме як Закон Грешема : погані гроші виганяють добро. Він, як правило, знаходить застосування і в техніці. Коли у вас є дві теоретично еквівалентні підсистеми всередині вашої системи, занадто часто гірша буде спричиняти занадто багато проблем, щоб зробити кращою варті використання, як ми бачимо тут.
Мейсон Уілер

"приклад проектування системи типу, яка": це речення не є повним
coredump

@MasonWheeler Гіршим є, дозвольте здогадатися, динамічна перевірка типу. Тож як тільки ви його введете, не варто проводити якийсь статичний аналіз?
coredump

1
@coredump - Поступове введення того варте, якщо ви погано взаємодієте з нетипізованим кодом. Наприклад, будь-який тип у TypeScript, як правило, сповіщає контролеру типу відмовитись, в основному викидаючи переваги системи типів, оскільки це може спричинити погіршення значення через велику кількість статично перевіреного коду. Набрана ракетка використовує контракти та межі модулів, щоб уникнути цієї проблеми.
Джек

1
@coredump Прочитайте статтю Clojure. З динамічним набором тексту, особливо зі всім стороннім кодом, у якого не було доступних статичних типів, справді накрутили речі за їх спроби покращити свою кодову базу статичними типами.
Мейсон Уілер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.