不确定dev2.0
分支是否已经处于可以开始寻求帮助的状态,但无论如何我都会这样做 :wink: 我在该分支中发生的主要变化下面列出,如何您能否快速测试一下,以及第一个 alpha 版本有哪些待处理的任务。 如果您有兴趣帮助他们中的任何一个,请在下面发表评论,以便我可以提供更多细节以共同努力💪
FableTransforms
隔离传递。 这应该使代码比寓言 1 更易于维护,其中优化通常应用于多个地方(特别是非柯里化优化,希望它在寓言 2 中工作得更好)。 然而,一些优化仍然需要在最后一次 Fable2Babel 传递中完成:尾调用和决策树(模式匹配)。git checkout dev2.0
cd src/tools
bash quicktest.sh --build-core
这将编译并执行同一文件夹中的QuickTest.fs
文件。 随意将其用作测试寓言 2 功能的游乐场(但请不要将其包含在您的 PR 中)。 第二次,如果src/js/fable-core
文件没有改变你可以运行bash quicktest.sh
(如果src/dotnet/Fable.Compiler
文件没有改变你也可以运行bash quicktest.sh --no-build
但是无论如何,使用 2.1.300-preview1 构建一个没有更改的项目应该很快)。
在 Windows 上,您应该能够使用 Git bash 运行脚本。
代码中散布着许多TODO!!!
注释,我可能应该自己处理这些注释。
由于插件不会包含在第一个 alpha 版本中,测试现在使用 Expecto API ,这更容易与 JS 测试运行器共享。 我已经转换了一些文件(ArithmeticTests、ArrayTests、ListTests),但其中大多数仍在等待一些爱。 我正在使用 Regex 将方法的签名更改为testCase
但为它编写脚本可能是个好主意。 主要挑战之一是,鉴于测试现在是列表中的值,出现在文件中间的额外函数必须移至顶部,这在某些情况下可能会影响其他值。
fable-core 中的 Set 和 Map 模块必须移植到 F#。 我部分是为 Set 做的(Map 也可以从FunScript repo 中获取,我最初是从那里窃取灵感的)。 我们需要确保它们被正确编译为 JS,公共函数名称正确公开,检查我们是否需要从以前的 .ts 文件(保存在src/tools/old
)中移植方法以及测试是否正常工作.
因为 AST 变化太大,大部分 Replacements 模块都需要重写。 我已经做了大约 1000 行,还有一千行。 这是一个有点乏味的任务,但如果有人疯狂到可以接受它,请告诉我。 也许最快的方法是让屏幕共享会话向您展示需要完成的工作,然后拆分剩余的代码,以便我们可以更快地完成。
不会包含在第一个 alpha 版本中的东西:bigint、反射、插件。
我希望现在有足够的信息,非常感谢您的帮助!
@alfonsogarciacaro我想我会在寓言核心任务中使用Set
以便我可以从这里获得灵感:)?
提醒一下,我们可以从许多回购中窃取灵感,
谢谢,@zaaack。 是的,FunScript 文件最初取自 FSharp.Core。 不确定它是否已经过时,但我倾向于更喜欢它,因为它已经在工作(寓言 1 中的Map.ts
最初也是它的翻译)而且我认为它已经砍掉了一些我们没有的东西在JS中需要。 关于 Bucklescript,我不确定模块是 OCaml 中的值这一事实是否有问题,F# 中的 Map 也必须符合某些接口,而我花费最多的时间是使具有自定义比较的类型作为键正常工作,这我想它在 OCaml 中也有些不同。
顺便说一句,Bigint 确实取自 FSharp.Core,但我认为我们会在以后的版本中移植。
谢谢@zaaack我会在端口上工作时记住这一点。
嗨,阿方索,我想在期待测试部分提供帮助
太好了@EdouardM ,谢谢! 如果您可以编写一个脚本来自动进行大部分转换,那就太好了。 如果你愿意,我们可以有一个简短的屏幕共享会议来展示需要做的事情:)
当然,我需要一个短暂的开球才能走上正轨。
从巴黎-马德里时间下午 6:30 开始,您今晚有空吗?
还是周日?
如果你是,请给我发送一个Skype电话邀请。
谢谢
爱德华
勒文。 2018 年 3 月 23 日 à 11:43,Alfonso Garcia-Caro通知@github.com
一个écrit:
太好了@EdouardM https://github.com/edouardm ,谢谢! 它会
如果你能写一个脚本来完成大部分转换,那就太好了
自动地。 如果您愿意,我们可以进行一个简短的屏幕共享会话
显示需要做什么:)—
你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-375619541 ,
或静音线程
https://github.com/notifications/unsubscribe-auth/AG_t3dil59Mz38u4cCN9f0JEZMyK7OLRks5thNHPgaJpZM4S03ig
.
我的电子邮件是:爱德华。 [email protected]
勒文。 2018 年 3 月 23 日 à 11:43,Alfonso Garcia-Caro通知@github.com
一个écrit:
太好了@EdouardM https://github.com/edouardm ,谢谢! 它会
如果你能写一个脚本来完成大部分转换,那就太好了
自动地。 如果您愿意,我们可以进行一个简短的屏幕共享会话
显示需要做什么:)—
你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-375619541 ,
或静音线程
https://github.com/notifications/unsubscribe-auth/AG_t3dil59Mz38u4cCN9f0JEZMyK7OLRks5thNHPgaJpZM4S03ig
.
不会包含在第一个 alpha 版本中的东西:bigint、反射、插件。
只是好奇,是否有路线图/计划在 Alpha 之后包含这些内容?
@jgrund没有具体的路线图,但 bigint 应该很容易添加(只需从 FSharp.Core 移植代码)并且反射也应该为稳定版本做好准备。 关于插件,我想收集有关它们如何使用的信息,然后共同决定我们应该如何提供它们或者是否需要它们。
谢谢你! 我确实必须对quicktest.sh
做一些小改动才能让它在 Git-Bash 中工作:
https://github.com/fable-compiler/Fable/blob/07ddd104cbeb6ad7adf98b6600ac3fe4d1fcfd70/src/tools/quicktest.sh#L30 -L33
将第 32 行更改为:
./quickfsbuild.sh --no-build
因为那里的bash
(我认为无论如何都不需要它?)导致 WSL 尝试启动,而我没有设置。
嗨@EdouardM! 这就是我们在 fsharpX 上讨论的关于更新测试的内容:
let ``(.*)``.*=
和替换testCase "$1" <| fun () ->
来更改测试的签名[<Test>]
, [<TestFixture>]
allTests
@alfonsogarciacaro我正在阅读 dev2.0 分支的源代码,试图成为处理Replacement.fs
其余部分的“疯狂者”,因为另外两个都被占用了😄。 我在从旧的Replacement.fs
移植parse
函数时遇到了一些问题, parse
函数依赖于returnType
,它存在于寓言中的Fable.ApplyInfo
1.0,但我在CallInfo
找不到它,不知道如何处理,你能给我一些帮助吗?
这是我的承诺:
https://github.com/fable-compiler/Fable/compare/dev2.0...zaaack :dev2.0?expand=1#diff-a34e57b30a53951ff9b99ce4076feaa4R1390
太好了@zaaack ,非常感谢。 是的,抱歉,我稍微更改了替换中函数的签名,使它们看起来更像其他模块中的函数,其中前三个参数通常是(上下文也可能排在第二位):
let myFableHelper (com: ICompiler) (range: SourceLocation option) (typ: Type) ... =
出于这个原因,我将返回类型(和范围)从CallInfo
移到了函数的第一个参数。 您可以使用let parse com r t info thisArg args =
(是的,我通常只使用t
并且我同意它不是很有意义)。
我也在替换模块中工作。 我可以处理集合(Seq、List、Array),而你完成其他功能,你觉得如何?
我最近添加了一个Helper
静态类型,以便使用带有可选参数的静态成员。 请查看现有代码以了解如何使用InstanceCall
、 CoreCall
... 助手。 其他注意事项:
CallInfo
传递它们。 如果是,则必须重新计算 arg 类型。ThisArg
是可选的。 如果存在,它将首先通过。 在寓言 2 中,类型实例成员实际上被编译为静态函数,这就是this
作为参数传递的原因。 ArgTypes
不包括ThisArg
。InstanceCall
kind 时, ThisArg
表达式将被编译为实际实例调用: thisArg.member(arg1, arg2...)
。现在应该足够了:) 如果您有任何问题,请与我联系,再次感谢您的帮助!
感谢您快速详细的回复,我明天试试。
我也在替换模块中工作。 我可以处理集合(Seq、List、Array),而你完成其他功能,你觉得如何?
太好了,我想我可以在工作日花两个小时,周末花一整天。
仅供参考,如果有人正在移植测试文件,则无需移植SetTests.fs
和MapTests.fs
我将这样做来测试模块集成。
此外,如果您使用 VSCode,您可以使用多项选择在一个文件中一次性完成所有工作。 在这里编写脚本似乎有点过于工程化:)。
谢谢 Maxime 我将处理测试文件的转换。
爱德华
2018 年 4 月 18 日 15:16,“Maxime Mangel”通知@ github.com 写道:
仅供参考,如果有人正在移植测试文件,则无需移植
SetTests.fs 和 MapTests.fs 我会用它来测试模块集成。
此外,如果您使用 VSCode,则可以使用多项选择来完成所有工作
一次在一个文件中。 编写脚本似乎有点过于工程化
这里 :)。
[图片:2018-04-18 15 14 27]
https://user-images.githubusercontent.com/4760796/38934173-59a5fc84-431b-11e8-81be-13f624e72817.gif
—
你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/fable-compiler/Fable/issues/1370#issuecomment-382382463 ,
或静音线程
https://github.com/notifications/unsubscribe-auth/AG_t3YjH5jvU1CXc-27gpz4-tGQNC7AHks5tpzyegaJpZM4S03ig
.
大家好! 我们仍然需要在src/js/fable-core/List.fs 中实现以下方法(注意它是一个 F# 文件,但它会在 JS 中分发):
这些已实现,但测试未通过:
这些有点特别,因为 Fable 需要注入IEqualityComparer
作为额外的参数。 我可以自己做,但如果你足够勇敢,你可以以sort
为例:
我已将失败的测试放在QuickTest.fs文件中,因此您应该能够重新编译 Fable + fable-core 并只需键入以下内容即可运行测试:
cd src/tools
sh quicktest.sh --build-core
有志愿者吗? ;) @ valery -vitko
我会看看这个周末我能做什么。
不幸的是,我在接下来的几周里都挤满了人。 (而且主要是与非编程相关的东西😢)。 没有我,玩得开心,伙计们。
我修复了 #1405 中的partition
和foldBack2
。
我会尝试做一些其他的低挂功能,做了truncate
和indexed
。
实现了unfold
、 tryItem
、 splitAt
和concat
。
你好呀! 上面的列表中还有一些缺失的方法。 有人在研究它们吗? 如果没有,我会试一试:+1:
@alfonsogarciacaro对不起,我以为他们都被带走了,剩下的我来。
公关: https :
考虑处理方法和接口的新方式的问题; 以下将如何处理?
type Base () =
abstract M: unit -> string
default __.M () = "base"
type A () =
inherit Base ()
member __.M () = "a" // NOTE: Not override, hides parent M
type B () =
inherit Base ()
override __.M () = "b"
let a = A ()
let b = B ()
printfn "%s" <| (a :> Base).M ()
printfn "%s" <| (b :> Base).M ()
Fable 2 将自己的成员实现为模块函数并在编译时解析引用。 但是,虚拟方法附加到 JS 原型,因此即使在向上转换对象之后也可以调用它们。 所以这个稍微扩展的代码版本(以显示对象如何调用父成员):
type Base () =
abstract M: unit -> string
default __.M () = "base"
type A () =
inherit Base ()
member __.M () = base.M() + " + a" // NOTE: Not override, hides parent M
type B () =
inherit Base ()
override __.M () = base.M() + " + b"
let a = A ()
let b = B ()
printfn "A: %s" <| a.M ()
printfn "A upcast: %s" <| (a :> Base).M ()
printfn "B: %s" <| b.M ()
printfn "B upcast: %s" <| (b :> Base).M ()
用最新的 dotnet-fable 2.0.0-alpha 编译成:
function Base() {}
function Base$$$$002Ector() {
return this != null ? Base.call(this) : new Base();
}
Base.prototype.M = function () {
return "base";
};
function A() {
Base$$$$002Ector.call(this, null);
}
(0, _Types.inherits)(A, Base);
function A$$$$002Ector() {
return this != null ? A.call(this) : new A();
}
function A$$M(__$$1) {
return Base.prototype.M.call(this) + " + a";
}
function B() {
Base$$$$002Ector.call(this, null);
}
(0, _Types.inherits)(B, Base);
function B$$$$002Ector() {
return this != null ? B.call(this) : new B();
}
B.prototype.M = function () {
return Base.prototype.M.call(this) + " + b";
};
const a = exports.a = A$$$$002Ector();
const b = exports.b = B$$$$002Ector();
(0, _String.toConsole)((0, _String.printf)("A: %s"))(A$$M(a));
(0, _String.toConsole)((0, _String.printf)("A upcast: %s"))(a.M());
(0, _String.toConsole)((0, _String.printf)("B: %s"))(b.M());
(0, _String.toConsole)((0, _String.printf)("B upcast: %s"))(b.M());
并打印:
A: base + a
A upcast: base
B: base + b
B upcast: base + b
@alfonsogarciacaro有没有办法完全禁用方法 -> 模块转换并获得干净的寓言 1 结果?
@vbfox不,抱歉。 这会影响寓言 2 的工作方式,不幸的是我没有资源来维护编译器标志以生成不同的输出:/
我完全理解资源问题,但很遗憾,因为它破坏了寓言和 JS 世界之间的许多兼容性,至少在任何地方使用类时:
(外部库进行方法检测的情况也需要创建接口,但这主要是好的做法)
它也正在远离 JS,您至少可以为课程感到自豪 - 即使我们并不那么关心 ;)
是的,生成的代码在寓言 2 中会有些 _不那么漂亮_。但是我希望还有其他优点(更好的摇树、静态调度)可以弥补这一事实。 关于在 Fable 中创建用于 JS 消费的库,它仍然是可能的,尽管我还没有看到任何实际示例。 而且我已经放弃在我的寓言项目中使用 Typescript,因为每当我尝试导入 .fs 文件时它总是会编译;)
与JS互操作的方式应该是接口。 Fable 现在将为接口生成带有未修改名称的对象包装器,因此您可以使用它们将类型发送到 JS 或其他语言。
@alfonsogarciacaro我真的很想在用 Fable 制作的 JS 中构建用于消费的库,但这是一个很大的痛苦,我放弃了它。 这是我没有比现在更多地使用 Fable 的最大原因。 我得出的结论是它仅适用于构建应用程序(无论是否为网络)。
感谢@Alxandr 的确认。 所以它在寓言 1 中已经很痛苦了,这意味着寓言 2 不能让它变得更糟 ;)
@alfonsogarciacaro确实如此。 而且我不认为转向静态会很重要(因为界面对象是一个很好的解决方案)。 但我确实认为它可能值得讨论为什么它非常痛苦,因为我认为其中一些可能会被寓言 2 解决。我认为主要问题是寓言核心存在于 nuget 而不是 npm(js文件)。 这意味着如果我有一个库和一个用 F# 构建的应用程序,我现在有Map
和List
等的两个副本。而且你也破坏了instanceof
.. .
真的。 实际上我们曾经试图解决这个问题(我认为在 Fable 0.7 中,当 fable-core 和 Fable 本身通过 npm 分发时)但是 fable-core 改变了很多,正确管理版本是一个噩梦(我们还必须保留版本适用于不同的模块系统)。 情况要好得多,因为寓言 1 是寓言核心文件只是由编译器注入,我们始终使文件保持同步。 我认为为 npm 创建 Fable 库是不可行的。 您要么创建一个 JS 库(暴露一个 JS API 表面,最好是捆绑),要么编写一个通过 Nuget 分发的 Fable/F# 库。
JS 生态系统非常广泛,Fable 为 F# 提供了许多机会。 不幸的是,我的影响力有限,在做出设计决策时无法考虑所有因素。 到目前为止,通常在不同领域引入 Fable:Elmish Web 应用程序、React Native、Electron ……感谢创建应用程序/库/工具的贡献者,然后我们共同努力使体验更容易。 但是除了几个小样本之外,我还没有看到用 Fable 创建的 JS 库。
是的,不,我完全明白。 我的“一劳永逸”解决方案可能是这样一种情况:您在 CI 上构建 fable-core(andy F#/js 库)并同时发布到 NuGet 和 NPM。 这样你也不需要 nuget 上的 F# 源文件(你只有构建元数据,但你需要 npm 导入名称)。 尽管如此,需要将很多部分组合在一起才能工作,并且可能需要在 nuget 包中存储一堆元数据(映射到生成的 JS 函数名称)。
所以,我今天一直在思考新的寓言输出,我想出了一些我想提出的问题,以防它们没有被考虑:
我自己并不是 JS 中的类的忠实粉丝,但是,它们确实服务于一个无法通过函数实现的重要目的(据我所知),即扩展本机类(如Map
或Array
)。 现在,我假设使用函数而不是类的主要原因是您需要处理多个构造函数,但我有理由确定可以通过其他方式解决(我会再看看更多明天)。 现在,为了清楚起见,我不是在谈论回到将所有东西附加到原型上的问题。 我只是在谈论使主要(或合成)构造函数成为一个类。 至于在没有new
情况下调用构造函数的能力,我认为这是一个相当有争议的问题,考虑到 F# 是一种类型化语言,而 Fable 应该能够静态地确定它是否需要发出new
与否取决于它调用的函数。
我已经看到很好地处理类型层次结构的代码,并允许类型检查和调用虚拟成员,这一切都非常好,但是新的输出如何与类型检查推测的接口一起工作? 以下面的代码为例:
type IFoo =
abstract Foo: string
type IBar =
abstract Bar: string
type FooBar () =
interface IFoo with
member __.Foo = "foo"
interface IBar with
member __.Bar = "bar"
let check (t: bool) =
if not t then failwithf "test failed"
let test () =
let foobar = FooBar ()
let foo = foobar :> IFoo
let bar = foobar :> IBar
let obj = foobar :> obj
check (foo :? FooBar)
check (bar :? FooBar)
check (foo :? IBar)
check (bar :? IFoo)
check (obj :? IFoo)
check (obj :? IBar)
()
我们现在可以关闭这个问题了,非常感谢大家帮助发布寓言2!
最有用的评论
仅供参考,如果有人正在移植测试文件,则无需移植
SetTests.fs
和MapTests.fs
我将这样做来测试模块集成。此外,如果您使用 VSCode,您可以使用多项选择在一个文件中一次性完成所有工作。 在这里编写脚本似乎有点过于工程化:)。