0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Erg言語を触ってみた

Posted at

Erg言語を触ってみた

ClaudeCodeに新し目の関数型言語について聞いてみたら紹介されたので、試しにやってみたという記事です。

結論から言うと、まだ開発中ということもあり、マニュアルなどのメンテもイマイチだったりして本格的に利用するのは厳しそうという感じでした。

Ergについて

Ergについては、このあたりで説明されている内容を読むと雰囲気がわかります。

インストール

インストール環境は MacOS 15.6.1 (Sequoia) で行っています。

基本的には以下の手順に沿ってインストールを行います。

ErgはRustを利用して実装されており、インストールするためにRustのビルド&パッケージマネージャであるcargoが必要になります。
cargoはRust関連パッケージのインストールで同時にインストールされるので、以下のrustup-initをインストールして下さい。

brew install rustup-init
rustup-init

以下のコマンドでErgをインストールします。

cargo install erg

失敗する場合は、cargoが古い可能性があるので以下のコマンドを実行してバージョンアップして下さい。

rustup update

手元の環境では以下のバージョンでインストールに成功しました。

cargo --version # cargo 1.89.0 (c24e10642 2025-06-23)

開発環境

VSCode

VSCodeのプラグインが公式からリリースされていますが、デバッグ機能等もまだ無いので、ターミナルから実行する方式で問題ないと思います。

vim

以下のような設定を入れておくと、ショートカットで実行ができるので楽です。

nnoremap [Exec] <Nop>
nmap <C-t> [Exec]
map <silent> [Exec]p :!erg run %<CR>
" Python出力
map <silent> [Exec]cp :!erg transpile %<CR>
" Pythonバイトコード(pyc)出力
map <silent> [Exec]cb :!erg compile %<CR>
" 型チェック
map <silent> [Exec]tc :!erg typecheck %<CR>
" フルチェック(ownership check, effect check, ...)
map <silent> [Exec]ta :!erg check %<CR>
" Linter (文法などのチェック)
map <silent> [Exec]f :!erg lint %<CR>

その他インデントなどの設定
Erg用のプラグインが今のところ存在しないようなので
ClaudeCodeで自動生成したところ、割といい感じのものを作ってくれました。
必要に応じて .vimrc ファイルなどに追記して下さい。

詳細
autocmd BufNewFile,BufRead *.er,*.erg set filetype=python

autocmd FileType erg setlocal
    \ tabstop=4
    \ shiftwidth=4
    \ expandtab
    \ autoindent
    \ commentstring=#\ %s

" シンタックスの設定
if !exists("b:erg_syntax")
  let b:erg_syntax = 1

  " Keywords
  syn keyword ergKeyword if else elif match case when do
  syn keyword ergKeyword import from as export
  syn keyword ergKeyword let var const mut
  syn keyword ergKeyword class trait impl enum union
  syn keyword ergKeyword fn proc macro
  syn keyword ergKeyword return yield break continue
  syn keyword ergKeyword try catch finally raise
  syn keyword ergKeyword and or not in is
  syn keyword ergKeyword for while loop
  syn keyword ergKeyword true false None

  " Types
  syn keyword ergType Int Float Str Bool
  syn keyword ergType Nat Ratio Complex
  syn keyword ergType Array Dict Set Tuple
  syn keyword ergType Option Result
  syn keyword ergType Self self

  " Operators
  syn match ergOperator "+"
  syn match ergOperator "-"
  syn match ergOperator "\*"
  syn match ergOperator "/"
  syn match ergOperator "%"
  syn match ergOperator "="
  syn match ergOperator "=="
  syn match ergOperator "!="
  syn match ergOperator "<"
  syn match ergOperator ">"
  syn match ergOperator "<="
  syn match ergOperator ">="
  syn match ergOperator "->"
  syn match ergOperator "=>"
  syn match ergOperator "|"
  syn match ergOperator "&"
  syn match ergOperator "!"
  syn match ergOperator "?"

  " Numbers
  syn match ergNumber "\<\d\+\>"
  syn match ergNumber "\<\d\+\.\d\+\>"
  syn match ergNumber "\<0x[0-9a-fA-F]\+\>"
  syn match ergNumber "\<0b[01]\+\>"
  syn match ergNumber "\<0o[0-7]\+\>"

  " Strings
  syn region ergString start='"' skip='\\"' end='"'
  syn region ergString start="'" skip="\\'" end="'"
  syn region ergString start='"""' end='"""'

  " Comments
  syn match ergComment "#.*$"
  syn region ergComment start="#\*" end="\*#"

  " Functions
  syn match ergFunction "\<[a-zA-Z_][a-zA-Z0-9_]*\>\s*("he=e-1

  " Variables (mutable)
  syn match ergMutable "\<[a-zA-Z_][a-zA-Z0-9_]*!"

  " Decorators/Attributes
  syn match ergDecorator "@[a-zA-Z_][a-zA-Z0-9_]*"

  " Highlighting
  hi def link ergKeyword Keyword
  hi def link ergType Type
  hi def link ergOperator Operator
  hi def link ergNumber Number
  hi def link ergString String
  hi def link ergComment Comment
  hi def link ergFunction Function
  hi def link ergMutable Identifier
  hi def link ergDecorator PreProc
endif

" Indentの設定
if !exists("b:erg_indent")
  let b:erg_indent = 1

  setlocal indentexpr=GetErgIndent()
  setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e
  setlocal autoindent
  setlocal nosmartindent

  function! GetErgIndent()
      let line = getline(v:lnum)
      let prevline = getline(v:lnum - 1)

      " 基本的なインデント
      if prevline =~ ':\s*$'
          return indent(v:lnum - 1) + &shiftwidth
      endif

      " ブロック終了
      if line =~ '^\s*}'
          return indent(v:lnum - 1) - &shiftwidth
      endif

      " デフォルト
      return indent(v:lnum - 1)
  endfunction
endif

ファイル拡張子

*.er もしくは *.erg を利用するとのことです。

コマンド

詳細はerg -hを参照して下さい。

ファイルの実行

# 以下のいずれかで実行する
erg sample.er
erg run sample.er
erg exec sample.er

Pythonコードに変換

erg transpile sample.er

バイトコードに変換(*.pyc)

erg compile sample.er

型チェック

# 以下のいずれかで実行する
erg tc sample.er
erg typecheck sample.er

文法

基本的には以下のマニュアルを読めば良さそうな感じです。

動作確認

以下のGitHub上に記載されているコードを貼り付けて実行すると...

l = [1, 2, 3]
assert l in [Nat; 3] # type checking
Error[#2604]: File sample.er, line 54, <module>

54 | assert l in [Nat; 3] # type checking
   :        -
   :        |- expected: {Nat}..Obj
   :        `- but found: {[1, 2, 3]}

TypeError: the type of `contains`::rhs (the 2nd argument) is mismatched


shell returned 1

ということでエラーになりました...
ちなみに、利用しているErgのバージョンは Erg 0.6.53 になります。

最後に

Ergは絶賛開発中ということで、おそらく古いバージョンでは動いていたのだと思いますが、マニュアルなどのメンテナンスが追いついていないので、公式で紹介しているコードでも動かないものがあるようです。

こちらのマニュアルで紹介されているコードに関しても、動いたり動かなかったりなので、今現在は、プログラミングを本格的に行っていくのは難しいのかなと思いました。

文法的には結構面白そうだったので、今後に期待したいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?