В чем основные различия между Scala и Frege (в парадигмах программирования)?

Scala и Frege - это типизированные функциональные языки, предназначенные для JVM.

Frege ближе к Haskell, у Scala более независимая история.

Но если мы не будем смотреть на синтаксические различия, каковы различия в допустимых методах программирования, стилях, концепциях между ними?


person imz -- Ivan Zakharyaschev    schedule 28.07.2013    source источник
comment
Frege - это нестрогий, чисто функциональный язык программирования в духе Haskell. Scala - это строгий язык . Scala не требует чистоты. И scala - это не попытка портировать Haskell на JVM, даже близко к этому. Вам следует искать вопросы о Scala и Haskell, например: Каковы различия и сходства систем типов Scala и Haskell? .   -  person senia    schedule 28.07.2013
comment
Анкур: функциональный язык - это язык, который позволяет писать программы с чистыми, ссылочно прозрачными функциями. Вы можете писать очень сложные программы на scala без каких-либо побочных эффектов. Итак, scala не просто выглядит как функциональный язык, это так.   -  person Rüdiger Klaehn    schedule 28.07.2013
comment
@ RüdigerKlaehn По вашему определению, практически любой язык является функциональным. Даже C - потому что, безусловно, можно избежать побочных эффектов в C и использовать указатели на функции для имитации HOF. Тем не менее, не многие люди назовут C функциональным языком. (Точно так же почти любой язык можно назвать объектно-ориентированным.)   -  person Shredderroy    schedule 28.07.2013
comment
@Shredderroy Scala предлагает достаточно конструкций и прямых предложений, которые помещают его в совершенно другую категорию, чем C w.r.t. функциональное программирование. Пожалуйста, без троллинга.   -  person 0__    schedule 28.07.2013
comment
@ RüdigerKlaehn Чистота на самом деле не является требованием функциональных языков. Возможность принимать функции в качестве аргументов, возвращать функции в качестве результатов и создавать новые функции во время выполнения (т.е. иметь синтаксис для анонимных функций, также называемых лямбдами) - это требования функционального языка. Haskell и Frege чисты, а это значит, что побочные эффекты изолированы. Scala, безусловно, функциональна И объектно-ориентирована. но он не чистый, в основном из-за практических проблем, связанных с запуском на JVM и взаимодействием с Java.   -  person Boyd Stephen Smith Jr.    schedule 08.08.2013
comment
Согласно определению в Википедии, в информатике функциональное программирование - это парадигма программирования, которая рассматривает вычисления как оценку математических функций и избегает состояния и изменяемых данных. Scala не требует чистоты, но имеет достаточно мощное чистое подмножество для написания очень сложных программ. С другой стороны, такие языки, как ruby, где даже базовые типы данных, такие как строки, являются изменяемыми, никогда не могут претендовать на функциональность, даже если у них есть механизмы для функций более высокого порядка.   -  person Rüdiger Klaehn    schedule 08.08.2013


Ответы (3)


ИМХО, оба - действительно хорошие языки, но что касается парадигм, Scala делает объектно-ориентированный объект лучше, чем Frege, но Frege работает лучше, чем Scala. Что касается различий, это сводится в основном к Haskell и Scala, поскольку Frege (или почти, см. Различия между Haskell и Frege здесь) Haskell для JVM.

  1. Вывод типов Фреге является глобальным, поэтому нам не нужно аннотировать типы так часто, как в Scala (локальный вывод).

  2. Во Frege модули - это просто пространства имен для типов и функций, тогда как в Scala модульная система лучше. http://2013.flatmap.no/spiewak.html

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

  4. Во Frege нет def vs val, и все является функцией. Следовательно, функции более первоклассные, чем Scala.

  5. Frege не имеет подтипов, но система типов определяет подтипность в собственных вызовах. Например, вы можете передать ArrayList функции, для которой требуется Java List.

    Поскольку нет подтипов, во Frege мы не можем расширять класс Java или реализовывать интерфейс на данный момент (может поддерживаться в будущем), поэтому нам нужен класс Java, который будет расширяться / реализовываться, но реализации методов будут передаваться от Frege. как функции.

  6. Из Scala легко вызвать Java, но в Frege класс / метод Java должен быть объявлен (только аннотации типа и чистоты) перед использованием. Например, чтобы использовать LinkedList в Java,

    data LinkedList a = native java.util.LinkedList where
        native add :: Mutable s (LinkedList a) -> a -> ST s Bool
        native get :: Mutable s (LinkedList a) -> Int -> ST s (Maybe a) throws
           IndexOutOfBoundsException
        native new :: () -> STMutable s (LinkedList a)
    

    Здесь, поскольку функции изменяют объект, они должны быть в ST монаде. Также обратите внимание, что здесь Фреге также обрабатывает null, возвращаемый из метода get, поскольку он аннотирован типом Maybe. Единственный способ null получить доступ к вашей программе Frege - это использовать собственный интерфейс, поскольку Frege не имеет понятия null.

    Другой пример: pure native floor Math.floor :: Double -> Double

    в котором говорится, что функция является чистой и, следовательно, подпись напрямую отражает исходную подпись Java без IO или ST.

  7. У Frege нет переменных, как в var Scala, и побочные эффекты более явны через типы. (Просто отсутствие null, var и явные побочные эффекты делают Фреге более интересным, по крайней мере для меня. В некотором смысле Фреге, как и Haskell, является «прекрасным императивным языком программирования» для JVM!)

  8. Будучи диалектом Haskell, Frege более естественен по отношению к функторам, аппликативам, монадам и другим функциональным «шаблонам» и имеет их в своей стандартной библиотеке, тогда как в Scala вам может понадобиться Scalaz.

  9. Frege по умолчанию является ленивым, но при необходимости можно включить строгость с помощью !, тогда как Scala по умолчанию является строгим, но имеет ключевое слово lazy для ленивого вычисления.

Тем не менее, будучи языками JVM, один язык может извлекать выгоду из другого. Однажды я портировал пример Akka на Frege. В конце концов, все сводится к строгости, чистоте, функциональности, объектно-ориентированности и типу вывода, а также к тому, насколько они важны для вас.

person Marimuthu Madasamy    schedule 28.07.2013
comment
Отличный, очень подробный пост. Хотя я бы предпочел, чтобы Frege заменял Haskell на JVM, тем более, что многие отождествляют Haskell с GHC, и нереально (мягко говоря) предполагать, что Frege когда-либо сможет удаленно поддерживать все классные функции GHC. - person Ingo; 29.07.2013
comment
Что касается языковых конструкций, модели оценки и сходства между библиотеками, он почти близок к Haskell для JVM (в идеальном случае, с небольшим преувеличением :), мы можем запускать код Haskell, как он находится на JVM с Frege) . Но, как вы сказали, это может и близко не подходить к тому, что предлагает GHC. Я отредактировал эту часть и добавил ссылку на различия Haskell-Frege на странице проекта. - person Marimuthu Madasamy; 29.07.2013
comment
Frege по умолчанию является ленивым, но при необходимости можно включить строгость с помощью !, тогда как Scala по умолчанию является строгим, но имеет ключевое слово lazy для ленивой оценки. Я также редактировал пост с этой точкой. - person Marimuthu Madasamy; 01.08.2013

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

Как уже указала @senia, scala является строгим и не чистым, что не означает, что вы не можете писать чистые функции (вы можете сделать это и в C), просто компилятор не будет его применять.

Фреге, OTOH ленив и чист, что означает, что все нечистые эффекты вынуждены жить в монаде ST или IO. Система типов очень важна для Haskell 2010, с классами типов и дополнительными типами функций более высокого ранга. Вывод типов работает в масштабах всей программы, за исключением функций с типами более высокого ранга, в которых по крайней мере полиморфный аргумент должен быть аннотирован. Вот пример:

both f xs ys = (f xs, f ys)

Для этой функции компилятор определяет тип:

both :: (α->β) -> α -> α -> (β, β)

Обратите внимание, что оба xs и ys получают один и тот же тип из-за применения f. Но теперь допустим, что мы хотим использовать функцию полиморфного списка, которую мы можем использовать с разными типами xs и ys. Например, мы хотим написать:

both reverse [1,2,3] ['a' .. 'z']

В его нынешнем виде это приложение будет ошибочным, потому что два списка имеют разные типы элементов и, следовательно, разные типы. Таким образом, компилятор откажется от списка символов.

К счастью, мы можем более точно сообщить компилятору, чего мы хотим, с помощью аннотации типа:

both :: (forall e.[e] -> [e]) -> [a] -> [b] -> ([a], [b])

Это говорит о следующем: мы передадим both функцию, которая выполняет некоторое преобразование списка, но не заботится о типе элемента списка. Затем мы передаем 2 списка с возможно разными типами элементов. И мы получаем кортеж с нашими преобразованными списками обратно. Обратите внимание, что код both изменять не нужно.

Другой способ добиться того же - написать:

both (f :: forall e.[e]->[e]) xs ys = (f xs, f ys)

а средство проверки типов делает вывод об остальном, а именно, что xs и ys должны быть списками, но могут иметь разные типы элементов.

Система типов Scalas полностью (насколько мне известно) поддерживает объектно-ориентированный подход. Хотя Frege поддерживает его лишь частично в отношении типов, импортированных для Java, но не поддерживает определение собственных объектно-ориентированных типов.

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

person Ingo    schedule 28.07.2013
comment
Хороший ответ! Незначительный нюанс: система эффектов для Scala, доступная в виде плагина: github.com/lrytz/efftp - person soc; 28.07.2013
comment
@soc Спасибо за ссылку. Тем не менее, я думаю, что утверждение о том, что Scala-the-unmodified-language не помогает изолировать эффекты, все еще оправдано. - person Ingo; 29.07.2013

Может быть, это не по теме, но Scala можно использовать для разработки приложений для Android (*), но Frege еще не использовался для этого успешно. (**) IIRC, это потому, что взаимодействие с существующими библиотеками Java в Scala намного проще, чем во Фреге, среди прочего.

(*) Пусть покупатель будет бдителен. Я сам делал только небольшие программы-примеры.

(**) Смеси Frege / Java использовались для приложений Android, но приложения только для Frege по-прежнему недоступны, AFAIK.

person Boyd Stephen Smith Jr.    schedule 08.08.2013
comment
Независимо от того, удачно это или нет, но есть, по крайней мере, доказательство концепции Android-приложения в сочетании Java / Frege. В этом контексте следует помнить, что последователей Скалы насчитывается 10 тысяч, в то время как Фреге, который существует не так давно и не очень хорошо известен даже среди знающих людей ФП, имеет, может быть, 200 человек, которые знают о его существовании. - person Ingo; 08.08.2013
comment
Возможны приложения для Android только на Scala. Во Frege вам нужно смешать немного Java, чтобы вы могли создать подкласс в нужных местах, IIRC. Однако это было неясно в моем ответе. Смесь Java / Frege вполне подходит для разработки под Android. Я добавлю примечание, чтобы уточнить. - person Boyd Stephen Smith Jr.; 09.08.2013