f# - 混淆元编程中的 F# 引用和模式匹配

标签 f# metaprogramming

1- 我真的很困惑在元编程中应用 F# 引用和模式,请提出一些在 F# 中处理这个概念的方法。

2- 你能告诉我一些 F# 引用和模式在元编程中的实际应用吗?

3- 有些人说他甚至可以通过 F# 制作另一种语言,如 IronScheme,是吗?

谢谢。

最佳答案

1- I'm really confusing on applying F# Quotation & Pattern on Meta Programming, please suggest some way to approach this concept in 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- Can you show me some real application of F# Quotations and Pattern in Meta Programming ?



与 OCaml 和 Lisp 等语言的引用机制相比,F# 引用机制在功能上极其有限,以至于我想知道为什么要添加它。此外,尽管 .NET Framework 和 F# 编译器提供了全速编译和执行引用代码所需的一切,但引用代码的评估机制比真正的 F# 代码慢几个数量级,这再次使它几乎毫无用处。因此,除了 Websharper 之外,我对它的任何实际应用都不熟悉。 .

例如,您只能在 F# 中引用某些类型的表达式,而不能引用其他代码,例如类型定义:
> <@ 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)

元编程是一种模式匹配非常有用的应用程序,但模式匹配是一种通用语言功能。您可能会欣赏 my article from the Benefits of OCaml about a minimal interpreter .特别要注意模式匹配是多么容易使其作用于每种不同类型的表达式:
> 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 期刊文章 "Language-oriented programming: The Term-level Interpreter" (31st December 2007) 的基础。 .

3- Some guys said that he can even make another language like IronScheme by F#,is that right ?



是的,您可以用 F# 编写编译器。事实上,F# 源自一个专门为元编程设计的语言家族,即所谓的 MetaLanguages (ML) 家族。

文章"Run-time code generation using System.Reflection.Emit" (31st August 2008)来自 F#.NET Journal 的文章描述了一个名为 Brainf*ck 的最小语言的简单编译器的设计和实现。您可以扩展它以实现更复杂的语言,如 Scheme。事实上,F# 编译器主要是用 F# 本身编写的。

在相关说明中,我刚刚完成了一个编写高性能序列化代码的项目,该项目使用反射在项目中使用 F# 类型,然后吐出 F# 代码来序列化和反序列化这些类型的值

关于f# - 混淆元编程中的 F# 引用和模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317912/

相关文章:

f# - 如何约束一个类型参数

parsing - 如何使用 FParsec 在 F# 中解析非常大的文件

f# - 在 F# 中,如何在不重新评估 seq 的情况下获取 seq 的头/尾

Ruby 包装函数

reflection - Grails/Groovy - 域对象 - 其属性映射

function - F# 生成随机数时的函数简洁性

visual-studio - 为什么 NUnit 测试适配器找不到我的 FsUnit 测试?

Python - 如果函数是一等对象,函数可以有方法吗?

ios - Swift 协议(protocol)泛型错误(ORM 实现)

python - 1 个类继承 2 个不同的元类(abcmeta 和用户定义的元)