Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

    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 monad. Также обратите внимание, что здесь Frege также обрабатывает null, возвращаемый методом get, поскольку он аннотируется с типом Maybe. Единственный способ, с помощью которого null может перейти к вашей программе Frege, - через собственный интерфейс, поскольку у Frege нет понятия null.

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

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

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

  • Будучи диалектом Haskell, Фреге более естественен в отношении Функторов, Применений, Монад и других функциональных "шаблонов", и в них есть стандартная библиотека, тогда как в Scala вам может понадобиться Scalaz.

  • По умолчанию Frege ленив, но при необходимости можно включить строгость через !, тогда как Scala по умолчанию строгая, но имеет lazy ключевое слово для ленивой оценки.

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

Ответ 2

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

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

Frege, 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 полностью (насколько мне известно) поддерживает OO. Хотя Frege поддерживает его только частично в отношении типов, импортированных для Java, но не поддерживает определение собственных типов OO.

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

Ответ 3

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

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

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