D言語のおはなし

※この記事は ICT Advent Calendar 2018 18日目の記事です.

昨日はICUに合格したらしいまなえです.

manaway1019.hatenablog.com

明日は,私が高専を去ることを心底悲しんでいるkurokojiです.

親しい人が離れていくというのは正直寂しいですよ.はい.

毎年私からの愛のこもったフリを受けるために,私の次の日に記事を書いちゃう可愛いやつです.

誤りがあるので言っておくと,僕のほうが先に18日に書く予定を入れていたのに,17日に後からわざと入れたのはあなたでしょ??? 事実を曲げることは良くないです.


D言語を流行らせたい

全人類が学ぶべき言語であるところのD言語.しかし実態はあまり知られていないように思います.

D言語くんは知っていますか?

D言語くん

Twitter等で一度は見たことがあると思います.何かと変なポーズなので,ほとんどの人が笑いの対象としか見ていないような気はしますが.

「変なマスコットキャラクターが存在する,ようわからん言語」

そのイメージを払拭するために,このD言語販促記事を書いてます.

あ,ちなみに今年の高専プロコン競技部門のソルバはD言語で書かれています.

https://github.com/kurokoji/procon29-kyogi/tree/master/nagatogithub.com

軽い文法の紹介

import std.stdio, std.array;

void main() {
  writeln("Hello, World!!");
  for (size_t i = 0; i < 10; ++i) {
    writeln(i);
  }

  /*
  上のfor文と同じ動きをする
  foreachの場合,iの型は何も書かなくても型推論してくれます
  */
  foreach (i; 0 .. 10) {
    writeln(i);
  }

  uint[] ar = [1, 2, 3, 4, 5];
  ar[0 .. 3] = 0; // [0, 0, 0, 4, 5]
  ar[0 .. $] = 6; // [6, 6, 6, 6, 6]
}

import std.stdio はC,C++でいう #include <stdio.h> みたいなもの.厳密には違うけど,まぁそれは置いておいて.

writelnprintf のような標準出力関数です.writeln は改行が最後に勝手に入ります.write なら入りません.

writelnprintf と違って書式文字列("%s %s" みたいな)は使えませんが,writefln で同様に出来ます.

一般的な for も使えますが foreach も使えます.

C,C++などと違って,unsigned intuint です.短くて良い.

で,ar[0 .. 3] = 0 みたいに配列のここから,ここまで0を代入する,みたいなのが一行で分かりやすく書けます.

if などは他の言語と大体一緒です.

面白い機能の紹介

D言語には面白い(しかも便利)機能がたくさんあります.

などなど.

いくつか紹介します.

UFCS(統一関数呼び出し構文)

import std.stdio;

int inc(int a) {
  return a + 1;
}

void main() {
  int n = 1;
  writeln(inc(n)); // 2
  writeln(n.inc()) // 2
}

writeln(inc(n)) は普通ですね. writeln(n.inc()) に注目していただきたい.

UFCSとは関数の第1引数を関数の前に持ってきて,まるでメンバ関数のように振る舞うことが出来る構文です. これによりメソッドチェーンがやりやすくなり,見た目もよりキレイになります.

CTFE(コンパイル時関数実行)

import std.stdio, std.string, std.conv;

bool[] Eratosthenes(ulong N)() {
  bool[] is_prime = new bool[N + 1];
  is_prime[2 .. $] = true;

  for (ulong i = 2; i * i <= N; ++i) {
    if (is_prime[i]) {
      for (ulong j = i * 2; j <= N; j += i) {
        is_prime[j] = false;
      }
    }
  }
  return is_prime;
}


void main() {
  // enumをつけることで,強制的にCTFEを発動させることが出来ます
  enum tmp = Eratosthenes!100000;
  write(">> ");
  auto n = readln.chomp.to!uint;
  writeln(tmp[n]);
}

readln.chomp.to!uint は標準入力から一行文字列を受け取って,改行を取り除き,uint に変換しています.

このプログラムはエラトステネスの篩という素数を列挙するアルゴリズムです. 通常,この計算はN が大きくなると計算が遅くなります.そこで,CTFE(コンパイル時関数実行)を用いると高速化が見込めます.

名前の通り,この機能はコンパイル時に関数を実行,つまり計算を行っています. これにより,実行時は列挙部分の計算は行わないため,高速化が可能です.

ただし,計算結果を埋め込むことになるので吐いたバイナリのサイズは大きくなります.

mixin

void main() {
  mixin("writeln(1);");
}

見慣れないものが出てきました. これをコンパイルして実行すると,1 と出力されます.

mixin は渡された引数の文字列をその場所にDのコードとして埋め込むことが出来ます. (条件がありますが,詳しい説明は省きます)

例えば,四則演算をする関数を作りたいと思ったとき.

int calc(string op)(int lhs, int rhs) {
  // Dでは~(チルダ)で文字列の連結が出来る
  return mixin("lhs" ~ op ~ "rhs");
}

void main() {
  writeln(calc!"+"(1, 2)); // 3
  writeln(calc!"-"(3, 1)); // 2
  writeln(calc!"*"(3, 4)); // 12
  writeln(calc!"/"(8, 2)); // 4
}

このようにすると関数を4つも書かなくて済みますね.

D言語に興味を持ったそこのあなた

D言語の公式ページでコードを実行して遊べます.ここ

Windows/Mac/Linux に対応してるので今すぐインストール. ここ

Windowsは上記のURLから飛んでインストーラ使って.

LinuxMacならスクリプトを叩く.

curl -fsS https://dlang.org/install.sh | bash -s

これらのD言語の魅力は使ってみて体感してください.特にC++ユーザーは気にいるはず.


明日はバターくんです.(誰かわからんぞ)

// ここに記事を貼る

Ubuntu18.04でneovim(or vim8)+LanguageClient-neovim+clangdでC++の補完をする

普段はMacで使ってますが,TwitterUbuntuで上手くいかなかった人がいるみたいなのでやってみました.

必須なやつ

インストール手順

dein.vimとneovimのインストール手順は省きます.(他に書いてる人がたくさんいるので)

clangd

clangも一緒にインストールしておきます

sudo apt install clang-6.0 clang-tools-6.0
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-6.0 100
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-6.0 100
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-6.0 100

LanguageClient-neovim

tomに書いてください.tomlに書いてない場合,適宜読み替えてください.

[[plugins]]
repo = 'Shougo/dein.vim'

# vim8用
[[plugins]]
repo = 'roxma/nvim-yarp'
if = "!has('nvim')"

# vim8用
[[plugins]]
repo = 'roxma/vim-hug-neovim-rpc'
if = "!has('nvim')"

[[plugins]]
repo = 'Shougo/deoplete.nvim'
hook_add = '''
let g:deoplete#enable_at_startup = 1
'''

[[plugins]]
repo = 'autozimu/LanguageClient-neovim'
rev = 'next'
depends = ['deoplete.nvim']
build = 'bash install.sh'
hook_add = '''
set hidden
let g:LanguageClient_serverCommands = {
      \ 'cpp': ['clangd'],
      \ }
let g:LanguageClient_loadSettings = 1
let g:LanguageClient_hasSnippetSupport = 0

set completefunc=LanguageClient#complete

nnoremap K :call LanguageClient#textDocument_hover()<CR>
nnoremap F :call LanguageClient#textDocument_formatting()<CR>
'''

結果

同様に,prabirshrestha/asyncomplete-lsp.vimを使ってもできます. これに関してはkutimoti氏が記事を書いてくれているのでどうぞ.

kutimoti.hatenablog.com

また,cquery-project/cqueryなどでも同様です.

kutimoti.hatenablog.com

HiDPI(Retina)環境にReaperを適応させて最高な気分になろう

いつの間にかReaperがHiDPIに対応していたので,記事にすることにしました.

どうもkurokojiです.

HiDPIとは

HiDPIとは「High Dot Per Inch」の略で「1インチあたりのドットがめっちゃある」みたいな解釈でたぶん合ってると思います.(たぶん)
これの何が嬉しいのかという話ですが,HiDPI表示をするとフォントやらUIやらが何かと綺麗に見えます.

例えば200×200の画像と1000×1000の画像を同じディスプレイで同じ大きさで表示するとき,1インチ中に含まれるドットが多い1000×1000のほうが綺麗に細かく表示されることを考えるとわかりやすいかもしれません.

HiDPI表示にする方法はググってもらうと直ぐに分かるので,ここでは書きません.

デフォルトの設定でPCがHiDPI表示になっている場合があって意識していない人もいるかもしれませんね.

動作を確認した環境

  • Laptop: MacBookPro(13-inch, 2016)
  • OS: macOS Sierra, Windows10
  • Reaper: v5.70/x64

HiDPIに対応させる

(注意: v5.34以降にしか対応してないので気をつけてください)

まず,ReaperのForumにあるHiDPI対応したThemeをダウンロードします.

ここの「...ReaperThemeZip」みたいに書かれてるリンクをクリックするとダウンロードが始まります. ダウンロードした「Default_5.0_hidpi.ReaperThemeZip」をダブルクリック,またはReaperにドラッグアンドドロップすると,インストールするぞ的なことを聞かれるので,従順になってやります.

メニューの「Options->Themes->Default_5.0_hidpi」を選択します.

Macユーザの皆さんはここで終了ですが,Winユーザの皆さんはまだやることがあります.

メニューの「Options->Preferences->General->Advanded UI/system tweaks...」をクリックして,「HiDPI mode(Windows 7+)」「Aware(experimental)」に変更します.

Reaperを再起動しましょう.

←デフォルト HiDPI→

フォントの部分を見ると分かると思うんですが,デフォルト状態の時よりもHiDPI状態のほうが美しくなっています.最高!! HiDPI万歳!!!!

これでReaperをHiDPIに対応させて綺麗な画面になりました!! 嬉しい!!

ま,CubaseとかポピュラーなDAWは大抵HiDPIに対応してると思いますが.