两天前,人工智能站报道 MIT 正式发布 Julia 1.0 的文章引发了极大的关注(20 多万的阅读量),对此编程语言既有批判者也有推崇者。如人工智能站了解到 Julia 在科学计算、数据处理行业很受欢迎。为了方便大家更了解这一新正式发布的编程语言,我们推荐 Julia 中文社区(中文社区介绍见文后)组织者之一罗秀哲新出炉的一篇简单教程。
文章地址:https://zhuanlan.zhihu.com/p/41802723
写在前面
这两天的媒体报道可能让一些人有了恐慌,但是我现在有一个诚恳的建议就是如果你完全没有编程基础,时间也不多的话(时间多了不是想学啥学啥),我建议你先学一下 Python,这并不冲突,因为 Julia 的语法本身和 Python 很像,1.0 之后也专门增加了一些 feature 帮助你更好地从 Python 转向 Julia。Julia 刚刚有了第一个长期支持版本,这还不意味着这个语言已经完全成熟,我想此时的 Julia 更像是彼时的 Python 2.0,还有很长一段路要走,但是已经非常的有前景。
那么什么人我会建议学习 Julia 呢?或者 Julia 在什么场景下也许能够有优势呢?我个人的体验是以下这里一类:
之前使用 Python 但是因为性能问题,经常需要使用 numba/Cython/C API/ctypes/etc. 等方式进行优化的人。Julia 或许能够帮助你解决两语言问题,并且获得可读性更好,更容易维护的代码。
之前使用 MATLAB,但是被一些付费功能困扰的用户(MATLAB 2018 也是不错的,但是要支持正版哈)
之前使用 Fortran 和 R 的用户,强烈建议使用 Julia(可以结合着用也,FFI 是很不错的)
之前使用 Sage/Octave 的用户,不妨尝试一下这个新玩意儿
之前使用 Mathematica 但是想开始做一些数值的用户,Mathematica 不是不能做数值,也可以调用 C/C++ 但是 Julia 不妨是相比其它工具更平滑的选择。
如果你之前的工作仅仅使用 Python 就足以胜任,那么不必着急,也不必恐慌,不妨在感兴趣的时候试试这个新东西,但是也完全可以等到 Julia 被大规模使用的时候再跟进。实际上从一开始像 MXNet 这样的 深度学习 框架就官方支持了 Julia,这些框架的 Python 用户转移过来也并不是什么难事,但是如果你本来就不担心自己程序的性能(很多时候这并不是一个大问题),那么其实不会体会到什么明显的不同和优势。但是这样说也并不完全正确,Julia 语言的优势不仅仅在其性能,也在其语言本身的设计。
此外,也要再三声明,虽然 Julia 可以写出高性能的代码,但是写出高性能的代码这件事情本身就很困难。虽然写起来像 Python,运行速度像 C 是我们的梦想,但是在现在这个阶段,并不是随便写一段 Julia 代码就真的能达到 C 的。Julia 只是给你提供了充分优化的空间,和(达到高性能代码的)相对容易的编程体验。
下载和安装 Julia
Julia 目前因为官网的服务器只有 AWS s3(他们也很穷)。所以国内的一些地区下载速度很慢:
链接:https://julialang.org/downloads/
大家可以试一试,然后也可以去 Julia Computing 公司提供的 Julia 全家桶(你可以把它理解为 Julia 版本的 Anaconda),最左边的 JuliaPro 是免费的:
链接:https://juliacomputing.com/
之前浙大的 LUG 搭建了一个镜像,但是维护的同学最近有一些忙,所以目前还没有更新到 1.0。但是其实你如果无法从以上途径下载,那么从境内的源里下载 Julia 0.6 也其实并不影响你先熟悉一些基本语法(这是这个教程的主要目的),境内的源的下载地址在这里:
链接:http://juliacn.com/downloads/
我们也会尽快更新。
然后还有一个叫做 Julia Box 的云服务很方便可以使用,里面有很多教程,都是 jupyter notebook,打开即用,全部都是在线的不用安装。但是唯一的缺点就是国内可能不一定能够正常访问到。
链接:http://suo.im/4S7gbT
使用什么编辑器
Julia 语言的社区不够大,此外由于不是像 rust 这样的静态编译语言,也不是像 CPython 这样的解释型编译器,在启动的时候有比较明显的 overhead,这个问题一直在优化(REPL 的启动时间已经从曾经的 1.0s 到了现在的 0.2s,依然和 IPython 这样的有明显差距),有 PL 的朋友私下和我说是 LLVM 的 JIT 不是那么好(像 nodejs 的 V8 这个问题就不是很明显)
所以在这个阶段选择一个合适的开发工具是非常必要的。目前支持最好,bug 最少的是 Atom 上的 Juno 插件,如果你下载 Julia Pro 那么会自带这个编辑器。如果你想选择手动安装,那么可以在这里下载 Atom:
链接:https://atom.io/
然后安装方法在这里有介绍:
链接:http://docs.junolab.org/latest/man/installation.html
或者我也推荐你安装 IJulia 之后,使用 jupyter notebook 和 jupyter lab 进行开发。
其它的平台也有支持,例如 Jetbrain 的各个 IDE 都可以使用由 @ 考古学家千里冰封等开发的插件。VS code 也有 Julia 插件,以及 Vim 也是有支持的。但是他们都还没有支持逐行执行和单独执行某一块代码的功能,这对于本身被设计得很像 Mathematica 的 Julia 来说没有执行一个 cell 的支持开发起来会时常被 JIT 的预热时间所困扰。
然后为了克服 JIT 的预热,避免重复启动编译器。如果你不重新定义(re-define)类型的话,可以试试 Revise.jl :
链接:https://github.com/timholy/Revise.jl
这是一个用于热加载 Julia 代码的工具,1.0 已经支持方法(method)的删除了。所以也能够方便你的开发。
其实和 Python 一样,在我日常使用中,作为动态语言,以及因为语法本身适合分块执行,我其实很少会用到断点和专门的 debugger,此外虽然有相关的包,在 1.0 的编译器里也为未来加入 debugger 提供了相关功能,但是目前还没有完善,你也许可以试试(但是我暂时不推荐):
链接:https://github.com/Keno/Gallium.jl
链接:https://github.com/timholy/Rebugger.jl
我怎么知道我要用什么包
Julia 有一个由社区维护的网站用来帮助你从 1900 多个包里找出符合你需求的 Julia 包:
链接:https://juliaobserver.com/
一般来说用比较新的,star 比较多的包会好一些。然后如果你觉得某个包不错,也请在 GitHub 上给一个 star。
基本操作
当你下载好了 Julia 之后,不论是 Julia Pro 还是单独的 Julia 编译器,你都可以先打开一个 REPL(交互式编程环境),类似于 IPython 之于 Python,Julia 的 REPL 支持了基本的代码高亮,文档查看等功能。但是 Julia 的 REPL 更强大(这件事稍后再说)。
Windows/Mac 用户:
双击 Julia 的三色图标,就能打开 REPL。在 Atom 里面的话在左上角有 Julia 一栏,点击里面的 open terminal 即可。
Linux 用户:
下载好以后去找到 bin 文件夹,然后把它加入你的 PATH 环境变量里去,以后就可以在命令行里直接通过 `julia` 命令启动 REPL。
树莓派用户和超算用户:
我相信你们是专业的,请阅读官网的教程吧。注意超算用户不用要求管理员安装也可以安装到自己的用户目录下的,设置好环境变量即可。然后有一些超算(比如中国科学技术大学的超算中心)Julia 编译器是很早就装好的,但是可能使用 module load 加载。
运行 Julia 的程序总的来说可以有三种方式(其实原理上它们都基本是等价的):
1. 执行一个 Julia 脚本,和其它 Julia 语言一样,你可以用如下命令执行 Julia 脚本,一般来说 Julia 脚本都以 `.jl` 作为扩展名。
julia script.jl
这个执行出来是没有报错高亮的,需要颜色请用以下命令执行
julia --color=yes script.jl
2. 如果直接启动 Julia 会进入到 REPL 里去
julia
你会看到
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.0.0 (2018-08-08)
_/ |\___|_|_|\___| |
|__/ |
julia>
也可以在这里运行 Julia 命令。
在 REPL 里面可以直接查文档,按?就会跳到 help 模式,在 0.7 之后(包括 1.0),按 ] 就会进入 pkg 模式,在这个模式下按?就会显示相关文档
(v1.0) pkg> ?
Welcome to the Pkg REPL-mode. To return to the julia> prompt, either press backspace
when the input line is empty or press Ctrl+C.
Synopsis
pkg> [--env=...] cmd [opts] [args]
Multiple commands can be given on the same line by interleaving a ; between the
commands.
Environment
The --env meta option determines which project environment to manipulate. By default,
this looks for a git repo in the parents directories of the current working directory,
and if it finds one, it uses that as an environment. Otherwise, it uses a named
environment (typically found in ~/.julia/environments) looking for environments named
v$(VERSION.major).$(VERSION.minor).$(VERSION.patch),
v$(VERSION.major).$(VERSION.minor), v$(VERSION.major) or default in order.
Commands
What action you want the package manager to take:
help: show this message
status: summarize contents of and changes to environment
add: add packages to project
develop: clone the full package repo locally for development
rm: remove packages from project or manifest
up: update packages in manifest
test: run tests for packages
build: run the build script for packages
pin: pins the version of packages
free: undoes a pin, develop, or stops tracking a repo.
instantiate: downloads all the dependencies for the project
resolve: resolves to update the manifest from changes in dependencies of developed
packages
generate: generate files for a new project
preview: previews a subsequent command without affecting the current state
precompile: precompile all the project dependencies
gc: garbage collect packages not used for a significant time
activate: set the primary environment the package manager manipulates
查看具体某个命令的文档可以
(v1.0) pkg> ?add
add pkg[=uuid] [@version] [#rev] ...
Add package pkg to the current project file. If pkg could refer to multiple different
packages, specifying uuid allows you to disambiguate. @version optionally allows
specifying which versions of packages. Versions may be specified by @1, @1.2, @1.2.3,
allowing any version with a prefix that matches, or ranges thereof, such as
@1.2-3.4.5. A git-revision can be specified by #branch or #commit.
If a local path is used as an argument to add, the path needs to be a git repository.
The project will then track that git repository just like if it is was tracking a
remote repository online.
Examples
pkg> add Example
pkg> add Example@0.5
pkg> add Example#master
pkg> add Example#c37b675
pkg> add https://github.com/JuliaLang/Example.jl#master
pkg> add git@github.com:JuliaLang/Example.jl.git
pkg> add Example=7876af07-990d-54b4-ab0e-23690620f79a
安装包在 0.7 之后都用 pkg 模式来安装,因为这个更方便,但是和 0.6 一样,如果你想使用代码来安装也是可以的,但是在 0.7 之后需要加载 Pkg 模块(0.6 不用)
using Pkg
然后安装你想要的包
Pkg.add("Example")
Julia 的 REPL 扩展性很强,比较有名的比如 OhMyREPL
甚至还可以在 Julia 的 REPL 里把 C++ 当成动态语言来写,按 < 键进入 C++ 模式(Julia 的 C++ FFI:Cxx.jl,暂时还没更新到 1.0,需要 0.6)
3. 第三种方式就是在 Atom 这样支持 cell 的编辑器里(notebook 也是类似的),在 Atom 中在某一行按 shift+enter 会单独执行这一行,结果会打印在这一行的后面。如果有多行的结果你可以用鼠标点击以下,就会展开。如果你选中了很多行,那么就会执行你选中的部分,结果显示在选中的部分最后。
notebook 里面的使用方法也是 shift + enter 和 Python 等其它语言类似。
下面的部分你可以在以上三种方式里的任意一种里执行。
本教程只是帮助熟悉语法,想要掌握 Julia 还请认真阅读手册(中文手册还在翻译中):
链接:https://docs.julialang.org/en/stable/manual/getting-started/
基本语法
正如所有的经典教程一样,我们先来学习怎么写 hello world:
在 Julia 里面写 hello world 可以这样写
> println("Hello World")
注意 在 Julia 里为了保证声明可以帮助你区分类型,String 是需要双引号的,字符使用单引号。
Julia 的字符串继承了 Perl 的字符串差值,正则表达式等,Stefan 的评价是他觉得 Perl 的字符串处理是最漂亮的,于是就抄了过来。
> name = "Roger"
> println("Hello $name")
这里 name 是一个变量,Julia 和 Python 一样,不需要声明变量,因为所有的变量都只是给值绑定了一个名字而已。然后对于变量插入,可以直接使用 $ 符号。
这将打印出
Hello Roger
当然对于比较长的表达式你也可以使用括号
> println("1 + 1 = $(1 + 1)")
这将打印出
1 + 1 = 2
我们上面提到了怎么绑定一个变量名:
> x = "Roger"
Julia 的变量名除了 ASCII 字符以外,还可以使用包括但不限于 UTF-8 的 unicode,比如甚至是中文
> 你好 = "Hello!"
还可以是 Emoji,输入 `:smile` 然后再按 `tab`
>