Julia体验 语言特性 元编程,宏

上接语言基础,就release-1.1来看,个人感觉这门语言和自己心中的理想国相距较远。这门语言因为受众不仅仅是程序员有很多让人迷惑的设计,但是奇怪的是它的语法等表象设计虽然暗示这不是专门为程序员准备的,内在的却提供了大量非程序员不可用的高级特性,库。

乘着热情还在,我挑一些有趣的东西再写写。

元编程

元编程即对代码进行处理的代码,可以使用Meta.parse()解析出参数代码的类AST表示,也可以使用quote ... end简化:

julia> multiStmt = Meta.parse(raw"a=1;b=2;t=a;a=b;b=t;println(a,b)")
:($(Expr(:toplevel, :(a = 1), :(b = 2), :(t = a), :(a = b), :(b = t), :(println(a, b)))))

julia> typeof(multiStmt)
Expr

julia> ast = quote
       x=1
       y=2
       res=x+y
       end
quote
    #= REPL[21]:2 =#
    x = 1
    #= REPL[21]:3 =#
    y = 2
    #= REPL[21]:4 =#
    res = x + y
end

julia> typeof(ast)
Expr

使用dump()获得更可读的表示:

julia> dump(multiStmt)
Expr
  head: Symbol toplevel
  args: Array{Any}((6,))
    1: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol a
        2: Int64 1
    2: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol b
        2: Int64 2
    3: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol t
        2: Symbol a
    4: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol a
        2: Symbol b
    5: Expr
      head: Symbol =
      args: Array{Any}((2,))
        1: Symbol b
        2: Symbol t
    6: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol println
        2: Symbol a
        3: Symbol b

expr有两部分,expr.head表示出这个表达式的类型,expr.args表示出剩余的参数:

julia> multiStmt.head
:toplevel

julia> multiStmt.args
6-element Array{Any,1}:
 :(a = 1)
 :(b = 2)
 :(t = a)
 :(a = b)
 :(b = t)
 :(println(a, b))

如果我们typeof head会发现,它是一种名为Symbol的类型:

julia> typeof(multiStmt.head)
Symbol

Symbol类型可以使用:name进行定义,也可以使用Symbol类型的构造创建:

julia> :str
:str

julia> typeof(:str)
Symbol

julia> Symbol("str2")
:str2

julia> typeof(Symbol("str2"))==typeof(:str)
true

最后我们使用eval()h函数传入Expr类型参数求值:

julia> eval(ast)
3

julia> eval(multiStmt)
21

这就给了我们一种使用代码操纵代码的方式:

julia> add = Expr(:call,:-,:a,:b)
:(a - b)

julia> a = 1
1

julia> b= 2
2

julia> eval(add)
-1

Julia的宏由macro ... end定义

julia> macro hello(name)
       return "hello,my name is "*name
       end
@hello (macro with 1 method)

julia> println(@hello("Andrew"))
hello,my name is Andrew

julia> println(@hello "Andrew")
hello,my name is Andrew

使用宏可以像函数一样加括号也可以宏名 参数1 参数2 ... 类似C/C++的宏的概念,Julia的宏也是实施的替换操作 所以上述println(@hello "Andrew")会被替换为println("hello, my name is Andrew"),可以使用@macroexpand获得展开后的结果

julia> @macroexpand println(@hello "Andrew")
:(println("hello,my name is Andrew"))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏函数式编程语言及工具

PICE(3):CassandraStreaming - gRPC-CQL Service

  在上一篇博文里我们介绍了通过gRPC实现JDBC数据库的streaming,这篇我们介绍关于cassandra的streaming实现方式。如果我们需要从一...

20100
来自专栏算法修养

POJ-1125 Stockbroker Grapevine

Stockbroker Grapevine Time Limit: 1000MS Memory Limit: 10000K Total Sub...

31840
来自专栏码匠的流水账

聊聊flink LocalEnvironment的execute方法

flink-java-1.6.2-sources.jar!/org/apache/flink/api/java/DataSet.java

21530
来自专栏ml

hdu 4034 Graph (floyd的深入理解)

Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Jav...

375110
来自专栏算法修养

UVALive 6933 Virus synthesis(回文树)

Viruses are usually bad for your health. How about ghting them with... other vir...

36570
来自专栏HansBug's Lab

3402: [Usaco2009 Open]Hide and Seek 捉迷藏

3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MB ...

34770
来自专栏个人分享

读写hdfs文件(工作笔记)

29230
来自专栏函数式编程语言及工具

Cats(1)- 从Free开始,Free cats

  cats是scala的一个新的函数式编程工具库,其设计原理基本继承了scalaz:大家都是haskell typeclass的scala版实现。当然,cat...

239100
来自专栏技术碎碎念

@RequestParam加与不加的区别

最简单的两种写法,加或不加@RequestParam注解 1 @RequestMapping("/list") 2 public String test...

36470
来自专栏HansBug's Lab

3101: N皇后

3101: N皇后 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special Judge Submit: 88 ...

34390

扫码关注云+社区

领取腾讯云代金券