2009-07-16 2 views
15

Много раз я слышал, что F # не подходит для конкретных задач, таких как пользовательский интерфейс. «Использовать правильный инструмент» - общая фраза.Что такое F #, недостающее OO или императив?

Помимо отсутствующих инструментов, таких как дизайнер WinForms/WPF/ORM, я не уверен, что именно отсутствует в F # - честно! Тем не менее, особенно с пользовательским интерфейсом, мне говорят, что C# просто делает это лучше. Итак, каковы фактические различия и упущения в F # при его императивном использовании?

Вот список, который я придумал:

  • Много отсутствующей поддержки инструмента

  • F # все еще бета

  • Ваши разработчики не знают, F #

    • Я бы не хотел рассматривать эти моменты, так как они не являются подлинными для F #
  • Mutables нуждаются в «изменчивости» или должны быть ref, ref need! разыменовать

  • Mutables назначения с < - и исх использует: = (они оба более 1 характер, чем просто =)

  • вал необходимо DefaultValueAttribute, чтобы получить значение по умолчанию

  • F # Безразлично» т испускают неявные интерфейсы

  • Защищенные члены более трудно иметь дело с

  • Нет автоматических свойств

  • Реализовано виртуальные члены на абстрактные классы требуют двух определений

  • Котировки к LINQ-Expression-Trees производит деревья немного отличаются, чем C#/VB (раздражающие для API, которые ожидают их выражения в определенном формате)

  • нет stackalloc

  • F # не имеют: условный оператор

  • Указатель s можно считать более громоздким в F #

  • Делегаты/события могут быть рассмотрены, возможно, более громоздким (я бы утверждать, что они легче, но, как минимум, они разные)

  • Нет автоматическое преобразование типов (например, int to float или неявные слепки)

  • Нет специальной поддержки синтаксиса для Nullable (C#? тип аннотации и? оператора, а также с использованием операторов по nullables.)

  • Нет автоматический общепринятому приведения к базовому типа базового класса или боксу (например: пусть х: OBJ = если верно, то 1 еще «привет» // это не typecheck)

  • Значение не может быть отброшены без предупреждения («игнорировать», чтобы обойти его)

  • не имеет синтаксис C-стиле :)

на вопрос: какие из них являются помехой для написания императивный или OO код ? Почему (короткие примеры)? Какие из них я пропустил? Каковы наилучшие обходные пути, и почему их недостаточно?

Обратите внимание:, я не говорю о написании так называемого идиоматического F #, и я, конечно же, не говорю о функциональном программировании. Меня больше интересуют строки «Если бы я заставил себя написать UI или императивный/OO-код в F #, используя F # OO/императивные функции и типы классов, что больнее всего?»

Bonus Если вы не знаете, F #, но использовать C# или VB.NET, и думаете, что это лучший инструмент для некоторых ситуаций, просьба указать специфические особенности языка и синтаксис вы находите привлекательные.

+4

Похоже, вы хотите, чтобы F # был C# или VB. Вы будете тратить много времени на писание в императивном стиле. – leppie

+1

Пожалуйста, не пойми меня неправильно. Многие из вещей, которые мне нравятся в списке, я думаю, что они позитивны. Нет, меня интересуют различия, которые разделяют на C# и VB.NET, что делает их лучше в таких задачах. Не общий «о, для этого не было», но «жесткий» недостаток защищенных членов означает, что F # просто не справляется с x y и z framework ». – MichaelGG

+0

Дизайнер не должен быть большой проблемой, так как вы можете использовать dll других. Как правило, это проблема только в небольших проектах. – Dykam

ответ

5

Что касается OO вещей, мой список может быть

  • Вы упоминали кое-что о интерфейсах и виртуалах, которые могут быть раздражающими или препятствием; недостаток авторезистов, о котором вы упоминали, также является позором
  • Для фреймворка OO иногда требуется много взаимно-рекурсивных классов, которые F # в настоящее время заставляет вас вставлять в один файл (в «тип ... и ... и ...» блок)
  • Если вам нужно вызвать две базовые конструктор в производном классе, вы должны использовать «явный» синтаксис класса (как указано here)

Тем не менее, F # имеют сильные позиции в отделе ОО тоже, как и вывод типа, локальные функции, сжатый синтаксис ... так что в целом я мог бы назвать это мойкой в ​​отделе «сильно OO».

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

(EDIT: Я также хочу вставляю, что, несмотря на то, что вы явно выбрать, чтобы исключить " инструментария "из вопроса, я думаю, что инструментарий имеет значение, и в этом отношении другие управляемые языки VS превосходят.)

+2

О да, вся рекурсивная вещь типа может быть болью. Но ... вы, ребята, это исправляете, верно? :) – MichaelGG

+0

Ваша ссылка OO выключена. Вы имеете в виду статическую печать? Или императив? – leppie

+0

@MichaelGG: В конце концов он будет исправлен, но неясно, сделает ли это первый релиз VS2010. ИМО это ограничение - единственное, что в принципе могло бы помешать вам создавать, например, 100-строчная структура OO в F #. – Brian

1

Моя самая большая боль со статически типизированными функциональными языками - это неспособность иметь переменные аргументы для метода, который должен быть случайны. Как функция карты. В F # вам нужно map2 map3 и т. Д.

С другой стороны, C# тоже не хватает этого, если вы не хотите идти через отражение.

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

+0

Для ненавистников PHP старайтесь не gag, но я все еще использую PHP для создания скриптов из-за его динамических типов и сопровождающих орды функций. – gradbot

+0

Хмм, я не думаю, что я сталкивался слишком много раз, когда мне нужно абстрагироваться от количества параметров. Но, опять же, F # и C# позволяют вам смешиваться в динамическом режиме, если вы склонны это делать по какой-то причине. Если вы хотите передать массивы объектов и динамически вызывать делегатов, проблем не должно быть. В большинстве случаев я бы не хотел отказываться от типа безопасности. – MichaelGG

6

Императивное программирование в F # намного лучше, чем люди заставляют вас поверить. F # match statement является удивительным.Почему другие языки не реализовали это, я не знаю. Что касается синтаксиса (mutable, ref и т. Д.), То с ними легко работать. Вы избалованы редкостью F # и легко жаловаться, когда синтаксис больше обычного. Tuples также великолепны. Они также будут в C# 4.0. Currying - еще один бонус для Imperative.

Относительно OO Я нахожу, что редко использую наследование в чистых проектах F # и предпочитаю композицию и интерфейсы. В основном это связано с использованием primary contructor, который позволяет использовать его параметры как частные свойства в ваших методах (не уверен, правильно ли я это сформулировал). Другие языковые конструкции, такие как сопоставление шаблонов, выталкивают вас и от наследования. Я не делал смешанных проектов C#/F #, поэтому я не могу комментировать это.

F # не все розы.

Моя самая большая проблема с F # и программированием игры - это производительность. Реализация в F # выполняется очень быстро, и я часто получаю прототип и работаю за то, что я хочу сделать в тот же день, когда я думаю об этом, но я нахожу, что переписываю код по причинам производительности чаще, чем на C#.

Отчасти проблема заключается в моей неопытности с функциональным стилем программирования, который заключается в использовании Seq, List, Map и всех их сопутствующих методов, таких как map, iter, fold, scan. Мое первое функциональное решение почти никогда не является самым быстрым, а мое первое процедурное решение почти всегда близко к лучшему. Я хочу сказать, что часть этого не я. В некоторых ситуациях это функциональное программирование не дает себе результатов.

Я использую меньше функциональных типов данных в F # сейчас, чем когда я начал.

EDIT:

Много месяцев прошло с тех пор как я отправил это, и я больше не имеют проблем с производительностью. Мои первые функциональные решения часто проще и почти оптимальны, и неизменные структуры данных просты. Единственные проблемы с производительностью, которые у меня есть сейчас, - это CLI, и я всегда могу сделать C++/cli, если мне нужно. Я использую некоторое наследование, кроме интерфейсов, но это только для анонимных объектов.

+1

Комплекс f # на XNA всегда будет более болезненным до тех пор, пока JIT не убедится в анализе надежно или не добавит GC поколения. Распределения, присущие его текущим (и, вероятно, фиксированным) реализациям многих из его полезных аспектов, таких как FastFunc, Tuples и закрытия. C# имеет такую ​​же проблему для делегатов, закрытий (и от 4.0 Tuples), но это не сильно их использует. Предотвращение распределения в жестких игровых циклах является важным соображением дизайна для производительности XNA. – ShuggyCoUk

+0

F # должен быть как минимум быстрее, чем C#, и часто * * быстрее. Если вам нужно переписать свой F # на C#, чтобы получить адекватную производительность, вы делаете что-то серьезно неправильное и должны научиться оптимизировать код F #. –

+1

@ Джон Харроп, действительно, я был. Будучи новичком в функциональном программировании, требуется некоторое время, прежде чем вы начнете приближаться к проблемам по-разному. – gradbot

10

Я не большой поклонник этого вопроса, поскольку он жалуется на то, что F # не поддерживает идиоматический C#. Например, я не думаю, что справедливо критиковать F # за использование < - и: = для назначения переменной, потому что язык делает вещи неизменными по умолчанию.

Независимо от того, есть несколько обязательных/объектно-ориентированных вещей, которые вы можете сделать в C#, которые вы просто не можете в F #.

  • F # не поддерживает вложенные классы. В C# вы можете объявить класс внутри тела другого класса как механизм для типов охвата. F # не поддерживает это.

  • F # не позволяет реализовать один и тот же общий интерфейс дважды. Например, в C# вы можете реализовать IComparable<int> и IComparable<string> того же типа.

  • В F # у вас должно быть архитектурное наслаивание. Из-за вывода типа F # вы можете использовать только те классы, которые были объявлены «до» или в том же «блоке» объявлений типов. В C# однако вы можете иметь любую ссылку на класс любой другой. (Это фактически накладывает некоторые хорошие методы программирования.)

  • F # не имеет «родной» поддержки LINQ, как ни в каком ключевом слове. Однако вы можете использовать LINQ API и лямбда-выражения для достижения того же результата.

То, что F # может делать, что C# не может:

  • дискриминированных союзы. Это делает тривиальным создание древовидных структур данных в F #, где в C# вам придется прибегать к сложной иерархии типов.

  • Асинхронные рабочие процессы. Эта функция библиотеки F # делает асинхронное и параллельное программирование намного более доступным, абстрагируя всю боль, связанную с APM.

  • Соответствие шаблону и активные шаблоны.

  • Единицы измерения для устранения ошибок, связанных с использованием неправильных устройств. (Например, добавление «ноги» на «м».)

  • т.д.

Вы не должны сосредоточиться на том, что F # не может сделать, как C# ', потому что весь смысл обучения F # должен быть представлен новый способ думать о решении проблем. Если вы пишете идиоматический код C# в F #, вы на самом деле ничего не получаете.

AFAIK F # не пропускает никаких «обязательных условий» для взаимодействия .NET/COM. В F # вы можете делать такие вещи, как out out и byref parameters, объявлять строковые литералы и поддерживать атрибуты только на что угодно.

+0

Да, я боюсь, я не очень четко изложил свою точку зрения. Я не жалуюсь на F # или критикую его, просто указывая на различия. Мой реальный вопрос: «Почему C# больше подходит для пользовательского интерфейса, чем F #», или что-то в этом роде. Я определенно не считаю, что это так, что C# часто или никогда не является «правильным инструментом». Я просто хотел посмотреть, сможет ли кто-то поддержать это. (Я чувствую себя больным, когда мне приходится писать на C#. Даже если я напишу «C#», я бы предпочел сделать это в F # и получить вывод, сопоставление шаблонов и т. Д.) – MichaelGG

+1

«Например, на C# вы могут реализовать IComparable и IComparable на одном и том же типе ». - не имеет большого смысла! – Casebash

0

Только для записи: F # имеет распределение стека - попробуйте бесконечную рекурсию, которая не является хвостом рекурсивной, и вы получите переполнение стека. Это действительно не отличается от распределения стека в C#, кроме вас, зная, что вы можете безопасно использовать хвостовую рекурсию F # (в C# это зависит).

Кроме того, я хотел бы указать, что когда вы попадаете в действительно тяжелый код, ориентированный на события, F # масштабируется лучше, чем C#, с тем чтобы вы могли создать фреймворк для выполнения «сантехники» диспетчеризации событий для обработчиков и т. Д. без сантехники, становясь большей частью вашего кода. Для простого пользовательского интерфейса C# или VB могут подойти больше людей. В сложных ситуациях F # выдвигается вперед, и лично мне нужна помощь в сложных ситуациях больше, чем простые.

+2

О, и я думаю, что прямо противоположно: «Конечно, вы теряете статическую безопасность, но она бледнеет по сравнению с дополнительным удобством написания краткого кода». Вы можете сэкономить 10% от вашего ввода, но вы потратите гораздо больше времени на выполнение отладки во время выполнения. Если вы хотите переменное количество аргументов, просто используйте список! Вы можете реализовать тот же универсальный монотип, который схема использует в F # очень просто, но вы можете сделать лучше и выбрать статическую типизацию именно там, где вы этого хотите. – RD1

+0

Я имел в виду прямой «stackalloc», чтобы получить указатель на блок памяти, который у вас есть в стеке. В F # я предполагаю, что вам нужно будет создать большую структуру и принять ее адрес. Но в целом это звучит так, будто вы говорите, что C# не имеет большого преимущества, и это было моим моментом. – MichaelGG