小编Mar*_*ger的帖子

类型化中间语言的语用学

编译的一个趋势是使用类型化的中间语言.Haskell的ghc与它的core中间语言,系统F-ω变体,是本体系结构[1]的一个例子.另一个是LLVM,它的核心是一种类型化的中间语言[2].这种方法的好处是可以及早检测构成代码生成器部分的转换中的错误.此外,可以在优化和代码生成期间使用类型信息.

为了提高效率,对类型化的IR进行类型检查,而不是推断它们的类型.为了快速进行类型检查,每个变量和每个活页夹都带有类型以便于类型检查.

但是,编译器管道中的许多转换可能会引入新变量.例如,规范化转换K(.)可能会转换应用程序

M(N)
Run Code Online (Sandbox Code Playgroud)

变成一个表达式

let x = K(M) in
let y = K(N) in x(y)
Run Code Online (Sandbox Code Playgroud)

题.我想知道编译器如何处理给新引入的变量赋予类型的问题.难道他们重新类型检测,在上面的例子中K(M)K(N)?这不是很费时间吗?它需要通过环境吗?他们是否使用AST节点中的映射来键入信息以避免重新运行类型检查?


  1. S. Marlow,S.Peyton Jones,格拉斯哥Haskell编译器.

  2. LLVM语言参考手册.

compiler-construction ghc intermediate-language compiler-optimization llvm-ir

24
推荐指数
1
解决办法
385
查看次数

在模板Haskell中的准引号里面的Typechecking

我正在努力熟悉Template Haskell,令我惊讶的是下面的代码编译ghc(版本6.10.4).


    main = do
       let
           y = [| "hello" + 1 |]
       putStr ""

这告诉我,准引号内没有类型检查.在阅读关于Template Haskell 的原始论文后,这不是我所期望的.而且以下程序不编译.


    main = do
       let
          y = [| "hello" && True |]
       putStr ""

这里发生了什么?

haskell types type-systems metaprogramming

20
推荐指数
2
解决办法
617
查看次数

Scala构造函数抽象

Scala中可以使用以下内容:

scala> val l = List
l: scala.collection.immutable.List.type = scala.collection.immutable.List$@7960c21a

scala> l ( 1, 2, 3 )
res0: List[Int] = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

换句话说,Scala具有更高阶的多态性.我想使用高阶多态来执行以下操作.

sealed abstract class A { def eval () : A }
case class A0 () extends A { ... }
case class A1 ( a : A ) extends A { ... }
case class A2 ( a : A, b : A ) extends A { ... }
....
Run Code Online (Sandbox Code Playgroud)

所以我有一堆case类,子类A,其构造函数不一定采用相同数量的参数.我也希望有一个'通用'案例类,如下所示:

case class ApplyA …
Run Code Online (Sandbox Code Playgroud)

polymorphism scala

7
推荐指数
2
解决办法
1087
查看次数

使用通配符运行多个shell命令

是否有一种简单的方法可以在Scala(或Java)中执行以下操作.我想从Scala进程运行命令行命令,例如:

 cd test && javac *.java
Run Code Online (Sandbox Code Playgroud)

作为动态生成的shell脚本.本javac *.java应在目录中出现test.通常很简单

 import scala.sys.process._
 ...
 "cd test && javac *.java".!
Run Code Online (Sandbox Code Playgroud)

要么

 "cd test && javac *.java".!!
Run Code Online (Sandbox Code Playgroud)

不起作用,因为Scala误解了&&和通配符*.我不知道为什么.

shell scala

6
推荐指数
1
解决办法
1909
查看次数

斯卡拉的尝试的monadic链接

考虑以下函数链接f,gh使用monadic for-ereherehension.

  for {
    x <- List ( 11, 22, 33, 44, 55 )
    y <- f ( x )
    z <- g ( y )
    a <- h ( z )
  } yield a
Run Code Online (Sandbox Code Playgroud)

如果f,g并且h都有签名:

  Int => Option [ Int ] 
Run Code Online (Sandbox Code Playgroud)

然后for-comprehension编译好.但是,如果我取代Option [ Int ]Try [ Int ],Scala的类型inferencer抱怨线路

  y <- f ( x )
Run Code Online (Sandbox Code Playgroud)

以下错误消息.

  error: type mismatch;
  found   : scala.util.Try[Int]
  required: scala.collection.GenTraversableOnce[?] …
Run Code Online (Sandbox Code Playgroud)

monads scala scala-collections

6
推荐指数
1
解决办法
348
查看次数

Erlang BEAM 机器的减少

Erlang是一种众所周知的编程语言,因其轻量级线程而闻名(除其他外)。Erlang 通常是用BEAM 机器实现的。Erlang BEAM 机器的描述 (H'97) 说

为了保证公平调度,一个进程在经过固定数量的减少后被挂起,然后从队列中恢复第一个进程。

我对这种减少的概念很感兴趣。根据 (H'97),只有以下 BEAM 命令算作减少:

  • C/CO/ResC : 调用本地/常驻 Erlang 函数
  • CL:丢弃当前堆栈帧。调用本地 Erlang 函数。
  • CEx/TrCEx:调用外部 Erlang 函数(跟踪或其他方式)。
  • CExL/TrCExL:丢弃当前堆栈帧并调用外部 Erlang 函数(跟踪或其他方式)。
  • M_C_r:加载参数寄存器 x(0)。调用常驻 Erlang 函数。
  • M_CL_r:加载参数寄存器 x(0)。丢弃当前堆栈帧。调用本地 Erlang 函数。

所有这些都涉及函数调用。相比之下,调用 C 函数(例如TrC/TrCO)和调用内置函数(例如由Bif_0_ 调用)不算作减少。

问题。在这个序言之后,这是我想知道的。

  1. 为什么减少用于线程之间的调度,而不是时间片?
  2. 为什么只有上述命令使减少计数器前进?
  3. (H'97) 中的描述有点过时了,当代 Erlang 如何处理调度?

(H'97) B. Hausman,Erlang BEAM 虚拟机规范

concurrency erlang multithreading scheduling vm-implementation

5
推荐指数
1
解决办法
1987
查看次数

为什么我可以证明⟦(∃x.P)∧(∃x.Q)⟧⟧⟹x.(P∧Q)?

我是伊莎贝尔的初学者,学习基础知识.令我惊讶的是,我刚才证明了

lemma "? ( ? x. P ) ? ( ? x. Q ) ? ?  ? x. (P ? Q)"
apply ( auto )
done
Run Code Online (Sandbox Code Playgroud)

在伊莎贝尔/ HOL.现在假设P和Q的范围超过任意谓词,这是错误的,只是将P实例化为x = 1,Q实例化为x = 2.

当然,错误必须在我身边,但我的误解在哪里?

isabelle

4
推荐指数
1
解决办法
255
查看次数