Чи є JavaScript функціональною мовою програмування?


135

Тільки тому, що функції є об'єктами першого класу, є закриття та функції вищого порядку, чи заслуговує Javascript, щоб його називали мовою функціонального програмування? Головне, що я думаю, що йому не вистачає, це «Чисті функції», і він не «відчуває» себе подібними до інших функціональних мов, як lisp (хоча це насправді не є вагомою причиною, щоб він не був функціональним мовою ...)


12
@slashmais: Ні! Це лише заважає бути чистою (лі) функціональною мовою. ML (принаймні сучасні діалекти) теж нечисті - але ніхто не наважився б назвати їх нефункціональними;)

4
Є багато мов, які зазвичай вважаються функціональними, але які не є чистими. Я не бачу, як це потрібно. Якщо ви хочете бути настільки суворими, більшість так званих мов OOP теж не є OOP. У кінцевому підсумку приблизно 95% усіх мов не є парадигмою.
jalf

6
Чому це важливо? Коли я кодую в C ++, мені байдуже, мова "OOP" чи ні. Мені важливо, щоб він мав певні функції OOP, і що він має пару функціональних функцій програмування, і багато функцій імперативного програмування, і багато загальних функцій програмування. Але незалежно від того, чи це "O-" мова OOP чи мова FP чи щось інше, не має значення. Так само, коли я кодую в JS, не має значення, FP це чи ні. Важливо те, що він підтримує безліч приємних функцій FP. Здається, це неправильне запитання.
яльф

3
@hvgotcodes: так? Не існує жодного правила, яке говорить, що це не так. Моє правило - це функціональна мова, якщо ви можете використовувати її для програмування у функціональному стилі. Оскільки Javascript має першокласні функції, закриття та лямбда, я вважаю, що ви можете, і що стосується мене, це функціональна мова. Очевидно, це не є чистим, але жодна з мов, які ми зазвичай вважаємо FP (SML, наприклад), не є жодною. Так справді, я думаю, що вам просто потрібно послабитись. Якщо це викликає посмикування очей, потрібно звернутися до лікаря.
яльф

3
@jalf, абсолютно. Мотивацією до цього питання я хотів знати, що думають мої однолітки та розумніші, ніж я.
hvgotcodes

Відповіді:


180

Повторюючи власну відповідь на подібне запитання,

Немає прийнятого визначення функціональної мови програмування.

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

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


Я б радив вам прочитати наступні пов’язані публікації блогу (а також коментарі під ними):


29
+1 для вказівки на те, що не існує універсального визначення та приведення деяких прикладів архетипних функціональних мовних особливостей JS не має.

1
Більш пізні версії реалізації Mozilla JavaScript (розміщені на 1.7) мають відповідність шаблонів у вигляді завдань руйнування: developer.mozilla.org/uk/New_in_JavaScript_1.7#section_20
jbeard4

У JavaScript є поняття partals і частково застосовують параметри, тож мені цікаво, чи ваше твердження про те, що він не підтримує це, є невірним?
johnbakers

2
@OpenLearner, часткове додаток підтримується майже всіма мовами, які я можу придумати, навіть C. Для певного визначення поняття "підтримка" все одно. Випадок із JS не відрізняється. Справа в тому, чи часткове застосування не є легким та першокласним на цій мові. У JS це не так. Якщо вам цікаво, що я маю на увазі, погляньте на OCaml або Haskell.
зниклий фактор

JavaScript підтримує незмінність afaik.
fka

26

Я б сказав, що це багатопарадигмічна мова.

EDIT: Це багатопарадигма і включає функціональні конструкції.


так, я згоден, що це суміш і кілька різних речей.
Ешлі Гренон

5
але це не відповідає на питання, чи є воно також функціональним. Бути мультипарадигмою означає підтримку декількох парадигм. Чи є однією з цих парадигм функціональне програмування?
jalf

15

якщо розтягнути і перекрутити термін «функціональне програмування» до точки філософських дискусій, це питання може бути знову відкритим. Однак тоді ви опинитесь на рівні корисних питань на кшталт "Чи справді C ++ є мовою програмування"?

Відповідь на ваше запитання на більш щоденному рівні - "ні" .

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

JavaScript має контрольний потік і розуміється як імперативна мова. З точки зору дизайну це, очевидно, не є функціональною мовою.


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

2
Він підтримує функціональне програмування настільки ж, як це робить C ++, якщо ви самі пишете відповідні основи для цього - стільки, скільки зможете імітувати імперативний синтаксис у, скажімо, Haskell з невеликою роботою. Тим не менш, синтаксис JavaScript призводить до думки про робочий потік, а не про оцінку функції. З цієї причини я (або більшість функціональних програмістів) вважаю застосування терміна "функціональний" занадто обширним.
шухало

@ user411768: ви хочете сказати, що функціональність мови залежить від дизайну її стандартної бібліотеки чи ні? Я ніколи раніше не чув цього визначення. У Java є більшість інструментів, необхідних для програмування у функціональному стилі (наприклад, закриття та анонімні функції), чого C ++ (на даний момент) не має. Я думаю, що це робить JS набагато більше FP, ніж є C ++. Той факт, що мова не змушує вас програмувати в стилі FP, не робить її "менш функціональною", чи не так?
jalf

1
(i) Стандартна бібліотека є частиною стандарту, як і синтаксичні ознаки, і підкреслює певний ідіоматичний та концептуальний стиль. Наприклад, "C ++ зі STL" сильно відрізняється від "C з класами". Це має вплив. (ii) JavaScript має орієнтацію на об'єкти, функції першокласного громадянина - функції досить ортогональні імперативу / функціоналу-дихотомії. Однак, він ні безпосередньо не реагує на каррінг, ні в чистоті, і ніколи для цього не призначався. (iii) Мої останні слова з цього приводу, див. перший абзац допису.
шухало

3
Твердження, що JavaScript та C ++ пропонують однакові зручності функціонального програмування, безумовно, помилкове. JavaScript робить функціональне програмування досить простим і простим без усіх брудних конструкцій, які ви повинні пройти через C ++, щоб досягти того самого. Є багато чудових C ++ кодерів, які чітко говорять про те, що функціональне програмування дійсно не рекомендується в C ++, однак статті про те, як робити функціональне програмування в JavaScript, є в достатку
johnbakers

9

Термін "функціональне програмування" мова настільки перевантажений в ці дні, що він майже марний. Є два домінуючі значення:

  1. Має першокласні функції
    • Javascript - це!
  2. Базується на функціях, що використовуються в обчисленні лямбда, з акцентом на уникнення стійкого змінного стану (часто замінюючи його параметрами, переданими функціям)
    • Як зазвичай пишуть, Javascript це не віддалено!

Оберіть своє значення, і тоді питання відповідає.


Чи є джерело, яке використовує "функціональне програмування" для позначення мов, функції яких є громадянами першого порядку ?.
шухало

@ user411768: Власне, інший відповідач пов'язаний зі статтею Вікіпедії, в якій використовується таке визначення. en.wikipedia.org/wiki/Javascript - Джоел Спольський також мав на увазі це визначення у своєму "Чи може це зробити ваша мова програмування?" повідомлення про переваги «функціонального програмування»
Чак

Ви зазначаєте, що, як зазвичай пишуть, JavaScript не використовує вашу другу точку, але це, звичайно, не означає, що програмісти не роблять саме цього, і що мова не підтримує таку функцію, тому що, безумовно, це робить
johnbakers

@OpenLearner: Ну так, але те ж саме стосується Java та багатьох інших мов, які, як правило, вважаються вкрай необхідними - ви можете писати їх у функціональному стилі, але це не щасливий шлях мови.
Чак

... але останні JS підтримали б це.
Erik Reppen

3

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


2

Для мене Javascript - це і імперативна мова, і функціональна мова, і ви можете використовувати його в будь-якому випадку, і навіть ( egad ) в обох напрямках. Або ви можете використовувати одну парадигму і ніколи не торкатися іншої. Тобі вирішувати. Я, як і ви, не думаю, що Javascript слід називати функціональною мовою, оскільки він дозволяє виходити з парадигми функціонального програмування і виходити з нього. Можливо, якби в ній була якась прагма, щоб обмежити вас лише використовуючи функціональні парадигми програмування, я думаю, це було б корисно. Але, підсумовуючи, я кажу, що це більше імперативна / процедурна мова з деякими функціональними функціями програмування.


Зважаючи на це, F # вже не можна назвати функціональним.
Ерік Мікельсен

1
Правильно. Згідно Вікіпедії, F # це саме те , що я тільки що назвав Javascript: «F # [...] є багатопрофільним парадигма мови програмування [...] , який включає в себе функціональне програмування, а також імперативні об'єктно-орієнтовані дисципліни програмування»
Брайан Onn

2

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


0

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

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


2
JavaScript орієнтований на об'єкти. OO не вимагає занять, проте він вимагає об'єктів.
інкогніто

3
Javascript не орієнтований на об'єкт, він заснований на прототипі.
Кріс

1
JavaScript програмує суп. Трохи цього і трохи того.
Андрій S

0

Javascript - до точки. Це дійсно залежить від того, як ви займаєтесь його програмуванням. Якби я кодував OO способом, чи не був би OO? Тож якщо ви просто кодуєте речі "функціонально", це було б функціонально. Я здогадуюсь, що це багатопарадигмальна мова, тому називати це лише одним не зовсім точним.


0

@petraszd Я трохи переписав ваш код, щоб отримати "новий" для оператора:

   
   function ffor(a, b, f){
     function it(i){
       if(i > b)return
       f(i)
       it(i+1)
     }
     it(a)
   }

   print("----" + new Date()+"----")

   var funcs = []
   ffor(0, 9, function(i){
     funcs.push(function(){return i})
   })

   ffor(0, 9, function(i){
     print(funcs[i]())
   })

Але я знаю, що цей спосіб має недоліки для великих циклів ...

Пов'язане питання щодо оптимізації хвостових рекурсій у СП

PS Опубліковано тут, тому що у вас є проблеми з форматуванням коду під час публікації в якості коментаря


0

У Javascript ви можете зробити щось подібне !!

// Data
var fruits = [
    { name: 'apple',  price: 5 }, 
    { name: 'orange', price: 10 }, 
    { name: 'lemon',  price: 15 }
]

// Request Data from magicURL
request('magicURL')
    .then(selectKeyOf('price'))
    .then(priceMethod('sum'))
    .then((result)=>{
        console.log(result) // 30
    })

Я створив сторінку github , щоб продемонструвати цю концепцію, і ви можете клонувати / переглянути мою реалізацію


0

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


-2

Що я справді ненавиджу у JavaScript (якщо ви намагаєтесь розглядати це як мову FP), це:

function getTenFunctionsBad() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push(function () {
      return i;
    });
  }
  return result;
}

function getTenFunctions() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push((function (i) {
      return function () {
        return i;
      }
    })(i));
  }
  return result;
}

var functionsBad = getTenFunctionsBad();
var functions = getTenFunctions()
for (var i = 0; i < 10; ++i) {
  // using rhino print
  print(functionsBad[i]() + ', ' + functions[i]());
}

// Output:
//   10, 0
//   10, 1
//   10, 2
//   10, 3
//   10, 4
//   10, 5
//   10, 6
//   10, 7
//   10, 8
//   10, 9

Вам потрібно зрозуміти середовище стека JS (я не знаю, якщо це правильний термін), щоб зрозуміти таку поведінку.

Наприклад, у схемі ви просто не можете створити таке (Добре, нормально - за допомогою посилань на основні мови Ви можете це зробити):

(define (make-ten-functions)
  (define (iter i)
    (cond ((> i 9) '())
          (else (cons (lambda () i) (iter (+ i 1))))))
  (iter 0))

(for-each (lambda (f)
            (display (f))
            (newline)) (make-ten-functions))

1
Гм, я думаю, що Javascript посилається на змінну, але не містить посилання на значення .
аерокод

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