Является ли Javascript функциональным языком программирования?


135

Javascript заслуживает того, чтобы его называли функциональным языком программирования только потому, что функции являются объектами первого класса, существуют замыкания и функции более высокого порядка? Я думаю, что главное, чего ему не хватает, - это Pure Functions, и он не «чувствует» себя как другие функциональные языки, такие как lisp (хотя на самом деле это не веская причина, чтобы не быть функциональным языком ...)


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

4
Существует множество языков, которые обычно считаются функциональными, но не являются чистыми. Я не понимаю, как это требование. Если вы хотите быть настолько строгим, то большинство так называемых языков ООП также не являются ООП. В итоге около 95% всех языков являются языками без парадигмы.
2010 г.

6
Почему это важно, хотя? Когда я пишу код на C ++, мне все равно, является ли язык "ООП" или нет. Я забочусь о том, что у него есть определенные функции ООП, и что у него есть пара функциональных функций программирования, и много императивных функций программирования, и много общих функций программирования. Но не имеет значения, является ли это языком ООП, языком FP ​​или чем-то еще. Аналогично, когда я кодирую в JS, не имеет значения, FP это или нет. Важно то, что он поддерживает много хороших функций FP. Кажется, это неправильный вопрос.
Джалф

3
@hvgotcodes: так? Там нет абсолютно никаких правил, утверждая, что это не так. Мое эмпирическое правило заключается в том, что это функциональный язык, если вы можете использовать его для программирования в функциональном стиле. Поскольку Javascript имеет первоклассные функции, замыкания и лямбды, я думаю, вы можете, и, насколько мне известно, это функциональный язык. Очевидно, что он не совсем чистый, но большинство языков, которые мы обычно рассматриваем как FP (SML, например), не являются такими же. Так что на самом деле, я думаю, вам просто нужно расслабиться. Если это заставляет ваш глаз дергаться, вам нужно обратиться к врачу.
Джалф

3
@ jalf, абсолютно. Мотивация вопроса была в том, что я хотел знать, что думают мои сверстники и люди, которые умнее меня.
hvgotcodes 19.10.10

Ответы:


180

Повторяя мой собственный ответ на аналогичный вопрос,

Там нет общепринятого определения функционального языка программирования.

Если вы определяете функциональный язык как язык, который поддерживает функции первого класса и лямбды, то да, JavaScript * - это * функциональный язык.

Если вы также учитываете такие факторы, как поддержка неизменяемости, алгебраические типы данных, сопоставление с образцом, частичное применение и т. Д., То нет, JavaScript * не является * функциональным языком.


Я рекомендую вам прочитать следующие связанные посты в блоге (а также комментарии под ними):


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

1
Более поздние версии реализации JavaScript в Mozilla (начиная с версии 1.7) имеют сопоставление с образцом в форме деструктурирующих заданий: developer.mozilla.org/en/New_in_JavaScript_1.7#section_20
jbeard4

В JavaScript есть понятие частичных функций и частичное применение параметров, поэтому мне интересно, если ваше утверждение, что оно не поддерживает это, неверно?
Джонбейкерс

2
@ OpenLearner, частичное применение поддерживается практически каждым языком, который я могу себе представить, даже C. Для определенного определения «поддержка» в любом случае. Случай с JS ничем не отличается. Дело в том, является ли частичное применение простым и первоклассным на этом языке. В JS это не так. Если вам интересно, что я имею в виду, взгляните на OCaml или Haskell.
фактор

JavaScript поддерживает неизменяемость afaik.
13

26

Я бы сказал, что это мультипарадигмальный язык.

РЕДАКТИРОВАТЬ: это мульти-парадигма и включает в себя функциональные конструкции.


да, я согласен, что это смесь и несколько разных вещей.
Эшли Гренон

5
но это не отвечает на вопрос, является ли это также функциональным. Быть мультипарадигмой подразумевает поддержку нескольких парадигм. Является ли одна из этих парадигм функциональным программированием?
Джалф

15

если вы растянете и перевернете термин «функциональное программирование» до точки философских дискуссий, этот вопрос может снова оказаться открытым. Тем не менее, вы попадаете на уровень полезных вопросов, таких как «Является ли C ++ действительно языком программирования»?

Ответ на ваш вопрос на более повседневном уровне - «нет» .

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

JavaScript имеет поток управления и концептуализируется как императивный язык. С точки зрения дизайна это явно не функциональный язык.


1
цель дизайна? Что вы имеете в виду? В последний раз, когда я проверял, одним из источников вдохновения была Схема. Я бы сказал, что совершенно ясно, что одной из целей его разработки была поддержка функционального программирования, а также множество других парадигм
jalf 18.10.10

2
Он поддерживает функциональное программирование в той же степени, что и C ++, если вы сами пишете для этого соответствующие основы - так же, как вы можете эмулировать императивный синтаксис, скажем, на Haskell с небольшой работой. Тем не менее, синтаксис JavaScript приводит к тому, что его считают рабочим процессом, а не оценкой функции. По этой причине я (или большинство функциональных программистов) считаю применение термина «функциональный» слишком обширным.
Шухало

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

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 не использует вашу вторую точку, но это, конечно, не означает, что нет программистов, делающих именно это, и что язык не поддерживает такую ​​функцию, потому что она, безусловно, делает
Джонбейкерс

@OpenLearner: Да, но то же самое относится и к Java, и ко многим другим языкам, которые обычно считаются строго обязательными - вы можете писать их в функциональном стиле, но это не счастливый путь для языка.
Чак

... но последний JS поддержит это.
Эрик Реппен

3

Я не думаю, что есть конкретное определение функционального программирования, однако многие вещи, которые люди считают «функциональным программированием», можно сделать с помощью JavaScript. Вот хороший краткий пример в этой статье.


2

Для меня Javascript является и императивным языком, и функциональным языком, и вы можете использовать его в любом случае и даже ( например, в обоих случаях). Или вы можете использовать одну парадигму и никогда не трогать другую. Тебе решать. Я, как и вы, не думаю, что Javascript следует называть функциональным языком, потому что он позволяет вам входить и выходить из парадигмы функционального программирования. Возможно, если бы у него была какая-то прагма, ограничивающая вас использованием только парадигм функционального программирования, то это было бы полезно, я думаю. Но, в заключение, я говорю, что это скорее императивный / процедурный язык с некоторыми функциональными возможностями программирования.


По этой причине F # уже нельзя назвать функциональным.
Эрик Миккельсен,

1
Правильно. Согласно Википедии, F # - это именно то, что я только что назвал Javascript: «F # [...] - это язык мультипарадигмального программирования [...], который включает в себя функциональное программирование, а также обязательные дисциплины объектно-ориентированного программирования»
Брайан Онн

2

Я склонен не думать о языках программирования как об одной конкретной парадигме, а о том, что они поддаются определенным парадигмам. Однако только то, что они поддаются определенной парадигме, не означает, что вы должны использовать эту парадигму. Вполне возможно писать объектно-ориентированные программы на C и писать императивные программы на ML. Не использовать определенную парадигму для решения проблемы, потому что язык не предназначен для этого, просто искусственно ограничивает себя (конечно, вы все равно должны учитывать ограничения языка при принятии решения, будет ли конкретное решение хорошим решением).


0

Ну, я бы не сказал, что это функциональное программирование, но тогда я бы сказал, что оно является объектно-ориентированным, и только сегодня один из друзей сказал, что он тоже не поместит его на эту полку.

Так что, хотя я бы не сказал, что это так, я думаю, есть место для мнений. У него есть классические особенности функционального программирования, у него нет других.


2
JavaScript является объектно-ориентированным. ОО не требует классов, однако требует объектов.
Инкогнито

3
Javascript не является объектно-ориентированным, он основан на прототипах.
Крис

1
JavaScript это программирование супа. Немного этого и немного этого.
Эндрю С

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]())
   })

Но я знаю, что этот способ имеет недостатки для больших циклов ...

Связанный вопрос об оптимизации хвостовой рекурсии в JS

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 содержит ссылку на переменную, но не содержит ссылку на значение .
aeracode

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