MLStyle.jl, 博采众长的可扩展pattern matching与代数数据结构


#1

repo: https://github.com/thautwarm/MLStyle.jl
英文站帖子链接 : https://discourse.julialang.org/t/mlstyle-jl-a-package-to-supply-algebraic-data-types-and-all-kinds-of-pattern-matching/13580

了解一下集成各个语言的pattern matching后一个语言是有多好用?


#2

@thautwarm
我macroexpand 了用来对ADT支持的@data宏 结果发现一堆nothing,但是功能却确实能正确使用!
然后去看源代码发现里面用了@eval,为什么? 用@eval是由什么特别的优点吗?


#3

运行时没有eval也没有nothing啊emmmm
eval是重写ast时拿module的元信息用的,准确的说,一般是拿struct的fields


#4

额…我再研究研究。 结构定义能用,但quote住之后expand开还是nothing。不知道是不是macroexpand函数要用的module不应该用MLStyle。

不过我有一个问题,就是这种abstract type的方法和Haskell那种天生的sum type相比会不会有性能损失啊? 同样类似的情况是 Union{nothing,Int} 来充当 Maybe Int,总感觉有种用运行时多态的感觉。觉得性能不如加个Tag(但github有个issue中有人提到说julia编译器内部已经隐形的加了Tag来提升性能,因此用户自己再加Tag就没必要了,不知是否属实)。


#5

损失肯定是有的。abstract type里面存了所有它的实现类型,你觉得这个和union有啥本质上的差别?


#6

现在的实现还不是很高效,未来的bootstrap后会优化到你人工写不出或者说非常难写出的高效代码。pattern matching不仅仅是语法糖啊。


#7

Union{nothing,T} 特别优化过 这是0.7的一个主要提升 没有性能损失 可以放心使用


#8
julia> maybex(x) = x < 0 ? nothing : x
maybex (generic function with 1 method)

julia> @btime maybex(1)
  0.025 ns (0 allocations: 0 bytes)
1

julia> @btime identity(1)
  0.025 ns (0 allocations: 0 bytes)
1

julia> @code_warntype maybex(1)
Body::Union{Nothing, Int64}
1 1 ─ %1 = (Base.slt_int)(x, 0)::Bool                                                                                                                    │╻ <
  └──      goto #3 if not %1                                                                                                                             │
  2 ─      return Main.nothing                                                                                                                           │
  3 ─      return x                                                                                                                                      │

证明