Заблуждение о F# цитаты, а шаблон мета-программирования

1-я действительно запутан в применении цитаты F# и шаблона для мета-программирования, пожалуйста, предложите какой-то способ подойти к этой концепции в F#.

2 - Можете ли вы показать мне реальное применение цитат и шаблонов F# в мета-программировании ?

3 - Некоторые ребята сказали,что он может даже сделать другой язык, как IronScheme на F#, верно ?

спасибо.

2 ответов


1-я действительно запутан при применении цитаты F# и шаблона на мета-программировании, пожалуйста, предложите какой-то способ подойти к этой концепции в F#.

механизм предложения позволяет внедрить код в код и заставить компилятор преобразовать этот код из предоставленного источника в структуру данных, которая его представляет. Например, ниже приведена структура данных, представляющая выражение f#1+2:

> <@ 1+2 @>;;
val it : Quotations.Expr<int> =
  Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
      [Value (1), Value (2)])
    {CustomAttributes = [NewTuple (Value ("DebugRange"),
          NewTuple (Value ("stdin"), Value (3), Value (3), Value (3), Value (6)))];
     Raw = ...;
     Type = System.Int32;}

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

2-Можете ли вы показать мне реальное применение цитат и шаблонов F# в мета-программировании ?

механизм цитирования F# чрезвычайно ограничен по функциональности по сравнению с механизмами цитирования таких языков, как OCaml и Lisp, до такой степени, что мне интересно, почему он был добавлен. Более того, хотя .NET Framework и компилятор F# предоставляют все необходимое для компиляции и выполнения цитируемого кода на полной скорости, механизм оценки для цитируемого кода на порядок медленнее, чем реальный код F#, который, опять же, делает его практически бесполезным. Следовательно, я не знаком с какими-либо реальными приложениями этого за пределами Websharper.

например, вы можете указывать только определенные типы выражений в F#, а не другой код, например type определения:

> <@ type t = Int of int @>;;

  <@ type t = Int of int @>;;
  ---^^^^

C:\Users\Jon\AppData\Local\Temp\stdin(4,4): error FS0010: Unexpected keyword 'type' in quotation literal

большинств механизмы цитаты позволяют вам закавычить любой действительный код на всех. Например, механизм цитирования OCaml может цитировать определение типа, которое F# только что вырвало:

$ ledit ocaml dynlink.cma camlp4oof.cma
        Objective Caml version 3.12.0

        Camlp4 Parsing version 3.12.0

# open Camlp4.PreCast;;

# let _loc = Loc.ghost;;
val _loc : Camlp4.PreCast.Loc.t = <abstr>

# <:expr< 1+2 >>;;
- : Camlp4.PreCast.Ast.expr =
Camlp4.PreCast.Ast.ExApp (<abstr>,
  Camlp4.PreCast.Ast.ExApp (<abstr>,
  Camlp4.PreCast.Ast.ExId (<abstr>, Camlp4.PreCast.Ast.IdLid (<abstr>, "+")),
  Camlp4.PreCast.Ast.ExInt (<abstr>, "1")),
  Camlp4.PreCast.Ast.ExInt (<abstr>, "2"))

# <:str_item< type t = Int of int >>;;
- : Camlp4.PreCast.Ast.str_item =
Camlp4.PreCast.Ast.StSem (<abstr>,
  Camlp4.PreCast.Ast.StTyp (<abstr>,
  Camlp4.PreCast.Ast.TyDcl (<abstr>, "t", [],
    Camlp4.PreCast.Ast.TySum (<abstr>,
    Camlp4.PreCast.Ast.TyOf (<abstr>,
      Camlp4.PreCast.Ast.TyId (<abstr>,
      Camlp4.PreCast.Ast.IdUid (<abstr>, "Int")),
      Camlp4.PreCast.Ast.TyId (<abstr>,
      Camlp4.PreCast.Ast.IdLid (<abstr>, "int")))),
    [])),
  Camlp4.PreCast.Ast.StNil <abstr>)

FWIW, вот пример в Common Lisp:

$ sbcl
This is SBCL 1.0.29.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* '(+ 1 2)

(+ 1 2)

метапрограммирование-это одно из приложений, где сопоставление шаблонов может быть чрезвычайно полезным, но сопоставление шаблонов-это функция языка общего назначения. Вы можете оценить моя статья из преимуществ OCaml о минимальном интерпретаторе. В частности, обратите внимание, как легко сопоставление шаблонов позволяет действовать на каждый из различных видов выражения:

> let rec eval vars = function
    | EApply(func, arg) ->
        match eval vars func, eval vars arg with
        | VClosure(var, vars, body), arg -> eval ((var, arg) :: vars) body
        | _ -> invalid_arg "Attempt to apply a non-function value"
    | EAdd(e1, e2) -> VInt (int(eval vars e1) + int(eval vars e2))
    | EMul(e1, e2) -> VInt (int(eval vars e1) * int(eval vars e2))
    | EEqual(e1, e2) -> VBool (eval vars e1 = eval vars e2)
    | EIf(p, t, f) -> eval vars (if bool (eval vars p) then t else f)
    | EInt i -> VInt i
    | ELetRec(var, arg, body, rest) ->
        let rec vars = (var, VClosure(arg, vars, body)) :: vars in
        eval vars rest
    | EVar s -> List.assoc s vars;;
val eval : (string * value) list -> expr -> value = <fun>

эта статья OCaml была использована как основа F#.NET журнальная статья "языковое Программирование: интерпретатор уровня термина" (31 декабря 2007).

3 - Некоторые ребята сказали, что он может даже сделать другой язык, как IronScheme F#, это правильно ?

Да, вы можете писать компиляторы на языке F#. Фактически, F# происходит от семейства языков, которые были специально разработаны для метапрограммирования, так называемого семейства MetaLanguages (ML).

статьи " генерация кода во время выполнения с помощью системы.Отображение.Emit " (31 августа 2008) от F#.NET журнал описал разработку и реализацию простого компилятора для минимального языка под названием Brainf*ck. Вы можете расширить это, чтобы реализовать больше сложные языки, такие как Scheme. Действительно, компилятор F# в основном написан на самом F#.

в соответствующей заметке я только что завершил проект, написав высокопроизводительный код сериализации, который использовал отражение для использования типов F# в проекте, а затем выплюнул код F# для сериализации и десериализации значений этих типов


F# цитаты позволяет пометить часть кода F# и получить представление исходного кода. Это ued в WebSharper (см., например,в этом уроке) для перевода кода F# на JavaScript. Другим примером является поддержка F# для LINQ, где код отмечен как <@ ... @> переводится на SQL:

let res = <@ for p in db.Products 
               if p.IsVisible then yield p.Name @> |> query

шаблоны это просто очень мощная языковая конструкция, но ничего более таинственного, чем, например,if. Этот идея в том, что вы можете сопоставить значение с шаблонами, и программа выберет первую соответствующую ветку. Это мощно, потому что шаблоны могут быть вложенными, и поэтому вы можете использовать его для обработки различных сложных структур данных или реализации обработки symbolc:

match expr with
| Multiply(Constant 0, _) | Multiply(_, Constant 0) -> 0
| Multiply(expr1, expr2) -> (eval expr1) * (eval expr2)
// (other patterns)

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

языки ввода вы можете использовать F# (как и любой другой язык общего назначения) для написания компиляторов и инструментов для других языков. В F#, это легко, потому что она поставляется с инструментами для создания лексеров и парсеров. См., например,введение.