Що означають «реіфікація» та «реіфікація» в контексті (функціонального?) Програмування?


82

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

Крім того, нетехнічне значення світу ("перетворення абстрактного конкрету") не допомагає мені зрозуміти, що на практиці означає переосмислити щось у коді.

Я якось повільно працюю з концепціями інформатики, тому практичні приклади з кодом були б непоганими. : P

Відповіді:


42

Тож я прочитав це, і це майже те, що це означає: взяти абстрактне поняття і зробити його конкретним. Або існує проксі, який представляє абстрактне поняття. Наприклад, у Lisp поняття абстракції та застосування процедур переосмислюється, коли ви використовуєте лямбди.

Сама по собі реіфікація є широким поняттям, а не лише застосовним до функціональних мов програмування.

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

Інший приклад - це коли ви намагаєтесь змоделювати концепцію. Наприклад, припустимо, що у вас є Groupклас і Userклас. Зараз існують певні абстрактні поняття, що описують взаємозв'язок між ними. Наприклад, абстрактне поняття того, Userщо є членом Group. Щоб зробити ці відносини конкретними, ви повинні написати метод із назвою, isMemberOfякий повідомляє, чи Userє a членом a Group. Отже, що ви тут зробили, це те, що ви переосмислили (зробили реальним / явним / конкретним) абстрактне поняття членства в групі.

Ще один хороший приклад - це база даних, де у вас є взаємозв'язки батьків і дітей між об'єктами. Ви можете описати ці відносини в абстрактному понятті дерева. Тепер припустимо, у вас є функція / метод, який бере ці дані з бази даних і створює фактичний Tree об’єкт. Те, що ви зараз зробили, переосмислило абстрактне поняття дерев’яних відносин між батьками та дітьми у фактичний Tree об’єкт.

Повертаючись до функціональних мов загалом, мабуть, найкращим прикладом реіфікації є створення самої мови програмування Lisp. Лісп був абсолютно абстрактною і теоретичною конструкцією (в основному лише математичним позначенням для комп'ютерних мов). Так залишалося до тих пір, поки evalфункцію Ліспа фактично не реалізував Стів Рассел на IBM 704:

Згідно з повідомленням Пола Грема в Hackers & Painters, с. 185, Маккарті сказав: "Стів Рассел сказав, дивись, чому б мені не запрограмувати цей евал ..., і я сказав йому, хо, хо, ти плутаєш теорію з практикою, цей евал призначений для читання, а не для обчислень. Але він пішов далі і зробив це. Тобто, він склав евал у моїй роботі в машинний код IBM 704, виправивши помилку, а потім рекламував це як інтерпретатор Lisp, що це, безумовно, було. по суті та форма, яку вона має сьогодні ... "

Тож Лісп був переосмислений з абстрактного поняття у фактичну мову програмування.  


2
Здається, що реіфікація існує у континуумі залежно від ситуації. У той час як абстрактний шепелявий перетворення був перетворений на мову програмування, сам по собі мова програмування є досить абстрактною формою концепції, що передає обчислення, яка повинна бути далі перероблена в машинний код і, нарешті, в 1s і 0s, а потім нарешті в електричні сигнали ... і т.д. Таким чином, реіфікація є якраз протилежною (подвійною) абстракції.
CMCDragonkai

25

Рейфікація

Реіфікація - це форма інстанції. Коли ви переосмислюєте концепцію, ви берете щось абстрактне та конкретизуєте, як і визначення словника, яке ви надали.

Ви можете переорієнтувати тип як термін, що населяє деяке абстрактне дерево синтаксису можливих типів.

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

template<typename T> class Singleton {
    public:
        static T& Instance() {
            static T me;
            return me;
        }

    protected:
       virtual ~Singleton() {};
       Singleton() {};
}

переорієнтовує синглтон-шаблон дизайну як шаблон у C ++.

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

Ви можете переосмислити мову як перекладач для цієї мови. Ідея Ларрі Уолла з Perl мови є виражена в якості інтерпретатора.

Ці дані, матеріалізувати і вакуумні пакети матеріалізувати терміни , як графіки , що представляють , як він структурований в пам'яті з поділом.

Роздум

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

Відображення системи типів у Java, C # тощо приймає конкретний клас мовою програмування та надає вам абстрактну структуру класу, надаючи доступ до списку членів ваших класів. Тут ми беремо конкретне поняття типу і генеруємо з нього абстрактний термін, який описує його структуру, відкидаючи певні значення.

Подібно до того, як ви можете перетворити мову програмування на реалізацію, іноді ви можете піти в зворотному напрямку. Хоча це зазвичай вважається поганою ідеєю, ви можете взяти реалізацію та спробувати відобразити специфікацію мови з бажаних властивостей її поведінки. TeX був реалізований спочатку Кнутом, без специфікації. Будь-яка специфікація TeX була відображена в реалізації Кнута.

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

Пакет відображення, який я підтримую, забезпечує метод reify, який приймає термін і видає тип, який його представляє, а потім метод Reflection, який дозволяє вам генерувати новий термін. Тут "конкретний" домен - це система типів, а абстрактний - це терміни.


21

З вікі Haskell :

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

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


15

Одне із способів, про яке я можу згадати (я впевнений, що є й інші!) - це перетворення класу на словник. Візьмемо Eqклас (забувши про /=оператор на даний момент):

class Eq a where
    (==) :: a -> a -> Bool

Якщо ми реіфікуємо цей клас, він стає:

data EqDict a = EqDict (a -> a -> Bool)

які можна побудувати, перевірити тощо. Також варто відзначити, що ви можете мати лише один Eqекземпляр на тип, але кілька EqDictзначень. Але автоматична побудова екземплярів (наприклад, отримання рівності для списків, коли у вас є для елементів) не працює; вам доведеться побудуватиEqDict [a] значення самостійно.

Процес реіфікації такий же простий (як для цього випадку):

reify :: Eq a => EqDict a
reify = EqDict (==)

Функція, що використовує Eqклас, може перетворити щось на зразок цього:

-- silly example, doesn't really do anything
findMatches :: Eq a => a -> [a] -> [a]
findMatches x ys = [ y | y <- ys, x == y ]

-- version using EqDict
findMatchesDict :: EqDict a -> a -> [a] -> [a]
findMatchesDict (EqDict f) x ys = [ y | y <- ys, f x y ]

Якщо ви розгортаєте EqDict і просто передаєте a -> a -> Bool, ви отримуєте такі ..Byфункції, як Data.List.nubByі друзі - подібний фокус для Ordпотенційних клієнтів Data.List.sortBy.


9

Навіть просто в контексті Хаскелла цей термін використовується дуже широко. Пакет reify Енді Гілла дозволяє приймати рекурсивні структури та перетворювати їх у явні графіки. Пост Sigpfe про продовження описує перетворення поняття "решта обчислень" у значення, яке можна передати. Шаблон Haskell має функцію reify (виконується разом із кодом TH загалом під час компіляції), яка при наданні імені значення Haskell повертає доступну інформацію про нього (де оголошено, тип тощо).

Що спільного у всіх цих випадках? Вони говорять про те, щоб взяти щось, про що ми можемо міркувати і знати, але яке ми не можемо безпосередньо програмно маніпулювати, і перетворити це на фактичне значення першого класу, яке ми можемо називати і передавати, як і будь-яке інше. І це, як правило, намір, який люди хочуть передати, коли вживають це слово.


2

Я знаю, що в RDF існує концепція реіфікації. Як заявив Тім Бернес-Лі :

Реіфікація в цьому контексті означає вираження чогось у мові, що використовує мову, так що це стає можливим для лікування мовою.

Я припускаю, що це щось на зразок роздумів чи самоаналізу. Сподіваюся, ви отримаєте тут кілька хороших відповідей!

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