たにしきんぐダム

プログラミングやったりゲームしてます

ヨーロッパの企業に日本からリモートで働くにあたっての手続きまとめ

tanishiking24.hatenablog.com

以前ブログに書いたのですが、3月からポーランドの企業に日本からフルリモートで週3程度で働かせてもらっています。国内では個人事業主として働いているのですが、働き始めるに当たり手続き周りでいろいろ不安なときに、先駆者達の体験談がとても参考になったので知見を共有してみる。

先駆者達のブログ

blog.amagi.dev

tatsumarutimes.com

手続きまわり

契約形態

  • 国内で開業届を出してフリーランス、企業とは業務委託契約を結ぶ形になっています
  • 日本国内に法人がない限り、日本から海外の企業で働くのは個人事業主になるしかないんじゃないかな

給与の受け取り

  • wise のマルチカレンシーアカウントを使うとなんか仕組みはわからないけど外貨の受け取りが可能な口座をシュッと作れて、少ない手数料でいろんな通貨に換金できるらしいのでそれを使った。
    • 口座の開設手続きはアプリ内で完結して、身分確認書類をアップロードして2日くらいで口座開設完了した。
  • どうやら給与は PLN/USD/EUR で受け取れるとのこと
    • PLN で受け取るのが一番いいのかもしれないけど(手数料の関係で)、wise では PLN は受け取れないようだったので、EUR で受け取ることにした。

wise.com


消費税

  • 海外取引は免税なので請求に消費税を上乗せしたりしない。益税もらえないの悲しいね。
  • 個人事業主の給与がすべて海外取引で、取引先に消費税を一切請求していない場合、あえて課税事業者になることによって(経費で発生したぶんの)消費税の還付を受け取れて便利らしい。
    • 僕はそうではないので免税事業者のまま。インボイス制度きたらどうなるんですかね

www.m-itakura.com


源泉徴収まわり

結局僕の業務は(ポーランド内で?)源泉徴収の対象にはならなかったのだが、ポーランド側で源泉徴収されてかつ日本国内でも所得税を収める必要があるとかなると二重課税されて辛い。

これを防ぐために租税条約というものが各国間で結ばれていて、取引先の会社側の国での源泉徴収が免除されたり減免されたりする。

www.nta.go.jp

租税条約とは?目的や適用例、届出書の手続きなどをわかりやすく解説 | THE OWNER

租税条約の正式名称は「所得に対する租税に関する二重課税の回避及び脱税の防止のための日本国と相手国との間の条約」という。名称が長すぎるため、通常は租税条約という略称が使用されている。

租税条約とは|二重課税を排除するための内容とは|freee税理士検索

租税条約の適用を受けたい時 租税条約では、国際交流促進の観点から、非居住者または外国法人の居住地国又は所在地国とわが国との間で租税条約が締結されている場合には、その租税条約の定めるところにより、その非居住者等が支払を受ける国内源泉所得に対する課税を軽減または免除することとしています。

ただし、この課税の軽減または免除を受けようとする時には、「租税条約に関する届出書」をその国内源泉所得の源泉徴収義務者を経由して、税務署に提出する必要があります。

日本-ポーランドの場合は源泉徴収税の減免

www.jetro.go.jp

Tax Residency Certificate(居住者証明書) を近所の税務署でもらって、それを取引先の企業に最初の給与受取日前に提出して完了。


VAT number

そもそも現状の日本の個人事業主には VAT number (ポーランドの場合 NIP) に対応するものは付与されない。

  • 法人の場合は法人番号がそれに対応し
  • インボイス制度の適格請求書発行事業者になると、登録番号がそれに相当する。

僕はまだ適格者じゃないのでそれに相当するものがなかったので、相手先にVAT numberないです〜って言ったらOKということになった。なんとなくマイナンバーだけ提出したけど必要だったのかよく分かってない。

tatsumarutimes.com

VAT number を要求してきたのはインボイス制度と同じように取引先側が仕入れ税額控除的なもののためだと思ってるけどあってるのかな? だとしたらマイナンバーないですで大丈夫なのか、取引先側は余計に税金払う羽目になってたりしない?誰か教えて下さい

biz.moneyforward.com

ぜんぜんわからない。おれたちは雰囲気で税金をやっている

Tests as Documentation

production code の設計についてはよく議論される一方、ユニットテストをどう書くべきかについてはあまり議論されることが少なく。とにかくカバレッジが高ければヨシみたいな感じで軽く扱われていることが多い気がする。

その結果、テストを書くときやとりわけテストを追加するときに "良くない" 方法でテストを追加/拡張してしまい、メンテナンスしにくく壊れやすい・(未来の自分でも)読んでも何を検証しているのか分からない、テストが落ちても不安だけを煽り何が問題なのか分からない、技術的負債が誕生してしまう。

詳しいことは本 ( XUnit Test Patterns など? 詳しい人は僕に紹介してください)を読んだりチームメンバーと議論するのが良いと思うが、この記事を読んでテストの書き方に対する意識を啓発できたらなと思っている。

理想を述べるのは簡単だけど現実は大変、頑張ろう


introduction

ユニットテストの役割のうち最も重要な事のひとつは、書いた・変更したコード(ユニット)が"期待された振る舞い"をすることを検証すること。これに加えて個人的に最も重要な役割だと信じているものが「ドキュメントとしてのユニットテスト」で、xUnit Test Patterns では Communicate Intent と呼ばれる原則として紹介されている。

ユニットテストは理想的には、あるプログラムユニット(関数やクラス)がどういう条件下で・どういう入力に対して・どういう出力を返すか(・またはモックライブラリを使ってどういう挙動をするか)を検証するように書かれており、"良い"ユニットテスト(意図が掴みやすいテスト)は

  • それを読むことでSUT(system under test)の期待する振る舞いの全体像を早く・正確に捉えることができる。
    • (プログラムを一行一行読んだり、更新されてるか(もしくは存在するかも)わからない仕様書と比べて)
  • メンテナンスしやすい
    • 複雑なコードより、わかりやすい簡素なコードのほうがメンテナンスしやすいのと同じですね

そのようなユニットテストを書くために何を気をつけるべきか、何をしないべきか


意図が伝わりやすいテストを書くために

Tests should be easy to write and maintain - Goals of Test Automation によくまとまっている。

Simple Test

テストは小さく、ひとつにつきひとつの条件をテストする Verify One Condition per Test という原則を満たすようにするべき。これによりそのテストが何を検証しているのかが分かりやすくなり、テストが落ちた時に Defect Localization が容易になる。

  • 必ずひとつのテストに一つの assertion にするべきというものではなく、ひとつのテストはひとつの "挙動" を検証するべきというもの。
    • 挙動の検証に複数の assertion が必要なら無理にテストを分割する必要はない
  • また条件と期待する結果の対応がはっきりしているなら Table Driven Testsi などを使うと良いかもしれない。

Expressive Tests

Test Utility Method などを利用して、テストを読むことで何が起きているのか・何を検証しようとしているのか分かりやすいプログラムにしましょうというもの。プロダクションコードに対しては当たり前によく言われていることですね。

Test Utility Method の欠点として、test reader が知るべきAPIが増えてしまうことがありますが、例えば assertContainsExactlyOneLineItem のような Intent Revealing Name を Test Utility Method につけてあげることで、意味の伝わりやすいテストを書くことができる。

Separation of Concerns

  • Keep Test Logic Out of Production Code
    • できる限りテストのために production code に back door のようなものを仕込んだりしないようにしましょう
    • テストとは、システムの挙動を検証するもので、テスト中にシステムの挙動が変わってしまっているのなら、production code をテストしていることにはならない。
  • Test Concerns Separately
    • 例えば(ユニットテストで)UIのテストの中でビジネスロジックをテストしてはいけない。
      • テスト対象の関係性が変更されるたびに、テストが壊れてしまう(ビジネスロジックの変更によりUIのテストが壊れるなど)。これにより、何が原因でテストが壊れたのか問題を分離することが難しくなる。
      • 簡単なように思えるが、システムが複雑で返ってきた値を何でもかんでもassertしているといつの間にか依存モジュールの挙動に左右されるテストが出来上がってしまうことは往々にしてある。SUTが真に成し遂げようとしている振る舞いを分析して最小限のテストを頑張って書こう。難しいけど。
    • うまく Test Double を使いましょう

アンチパターン

上の項と多少内容が重複するが、xUnit Test Patterns では(意図や挙動が)分かりにくいテストのことを Obscure Test と読んでいて、そのいくつかの原因に関する考察が紹介されている。

Eager Test

  • とにかく一つのテストで何でもかんでも assert しまくってしまっているテスト
  • Verify One Condition per Test 原則に従いましょう

Mystery Guest

  • 暗黙的な事前条件(test reader が気づくことができない条件)がテストの結果に影響しているおり、テストを読んでもどういう条件下でその出力が得られるのか分かりにくい状態
  • 例えば、外部ファイル・他のテストなどによって追加されるDBのデータ・ランダムに生成されたデータ
    • fake dataに意図せずテストが依存してしまうことはよくあるし気づきにくい。個人的にはfake dataの利用は局所的にしていきたいと思っている(例えばテストデータのオブジェクトそのものを生成するのではなく、オブジェクトのうち関心のないフィールドに対してだけ利用するなど)

General Fixture

  • ひとつの Shared Fixture がtoo manyテストのために働いている状態
  • Mystery Guest と同じように、巨大な Shared Fixture が設定したデータにテストが依存しており test reader がテストを読んでもどういう条件下でその出力が得られるのか分かりにくい状態
  • Test fixture は Minimal Fixture を目指すべき

Irrelevant Information

  • テストの入出力に、SUTの挙動に関係のないデータが大量に記述されている状態
  • SUT の動作に本当に影響を与えるものがどれか分かりにくい、どのassertionがこのSUTが満たすべき振る舞いを検証しているのか分かりにくい
  • constructor や factory method への直接呼び出しを、関連情報のみをパラメータとするCreation Methodの呼び出しに置き換えよう
    • テストにとって重要でない値は、Creation Methods の中でデフォルト化 or ダミーオブジェクトに置き換えて隠蔽する。こうすることで、test reader に対して「表示されない値は、期待される結果には影響しません」と伝えることができる。

Hard-Coded Test Data

例えば以下の例では、30 とか 19.9 のような hard coded された数字を入力し、結果として 69.96 などの値を期待しているが、これが何を意図した値なのかが分からない (69.96 はどこから来たんだ?)

we might still miss the relationship between the unit price (19.99), the item quantity (5), the discount (30%) and the total price (69.96.)

   public void testAddItemQuantity_severalQuantity_v12(){
      //  Setup Fixture
      Customer cust = createACustomer(new BigDecimal("30"));
      Product prod = createAProduct(new BigDecimal("19.99"));
      Invoice invoice = createInvoice(cust);
      // Exercise SUT
      invoice.addItemQuantity(prod, 5);
      // Verify Outcome
      LineItem expected = new LineItem(invoice, prod, 5,
            new BigDecimal("30"), new BigDecimal("69.96"));
      assertContainsExactlyOneLineItem(invoice, expected);
   }

http://xunitpatterns.com/Obscure%20Test.html から引用

意味が伝わりやすい定数にしてあげたり、無関係な値は Creation Method によって隠蔽してあげるなどしましょう。

Indirect Testing

  • プレゼンテーション層などの中間オブジェクトを通してビジネスロジック(SUT)をテストすることなど
  • 中間オブジェクトを通してSUTの挙動を観察することになるので、入出力が複雑になり分かりにくい。
  • 原因としては product code がテストしにくい設計になっている可能性が高い。

参考

近況

キャリア的にもアカデミア的にも私生活などで大きなアップデートが多かったのでブログ書いた!


仕事

ポーランドのIT企業にリモートで働き始めました

  • 2022年3月から VirtusLab という会社で Scala (Tooling) Engineer として週3で働いています。
  • 本社はポーランドのKrakowですが
    • 公用語は英語
    • ポーランドを中心にヨーロッパ各地からリモートで働く人も多い、部署(会社?)の中ではアジア人は僕だけっぽい
  • OSSScalaの開発支援ツール(Scala3や、IDE(metalsやビルドツールの一部など)の開発をしています。
    • 開発支援ツールの開発はいつか本業にしたいなと思っていたことなのですごく嬉しい。がんばります!!!!!!!

virtuslab.com

今の所Krakowへの移住は考えてない(良いところ だけど寒いの苦手 & 知り合いのいない国に単身移住するの勇気いりすぎませんか)。年に1回くらいはオフィスに顔出しに行きたいなぁとは思っている。

給与面は物価の違いなどもあり日本より水準が少し低めですが、納得いく額をいただいています。

フリーランスになりました。アルプ株式会社で副業させていただいています

国内だとアルプ株式会社さんで副業(?)させていただいています。

ぼそっとつぶやいたところご連絡をいただき、爆速でオファーをいただきました。本当にありがとうございます...。

  • 基本的にバックエンドエンジニアとしてScalaを書きつつ、少しだけReact書いたりしてる。
  • 採用している技術も面白いのですが、プロダクトのドメインもめちゃくちゃ複雑で、それをうまいこと仕様とプログラムに落とし込むという感じでとても面白いです。
  • Scala関連だと scalac-profiling を使ってプロジェクトのフルビルドにかかる時間を50-60%くらい削減したのが楽しかった。

thealp.co.jp


大学院

研究 - PX/22 というプログラミング体験に関するワークショップで発表しました

  • 2021年4月から東京工業大学 情報理工学院数理計算科学系の修士課程で研究しています。
  • 研究テーマの方向性は、一貫してコードリーディングの支援ツールなのですが以下のような変遷をたどって最終的にコード理解のためのnote takingツールに落ち着いた。
    • 機械学習を使ったプログラムの要約 -> 機械学習を使ったAPI利用例の収集生成 -> プログラムの可視化 -> コード理解のためのnote taking

docs.google.com ↑研究室内の発表 + 先日の ScalaMatsuri で発表した資料。

ある程度のサーベイと、簡単なプロトタイプはできていたのでPXというプログラミング体験に関する国際ワークショップにショートペーパー投稿 & 発表しました。コロナなかったらポルトガル行けてたのか...と思うとめちゃくちゃ悲しい、コロナゆるせん。

2022.programming-conference.org

勉強

  • 研究室の輪講でTaPLを読んだ
    • オンラインだったのですが Miro のホワイトボードに証明を書いて、それをみんなでゴチャゴチャ言うという形式
    • 1人で読んでも分かった気になって適当に読み進めてしまっていたと思うので、型システムに詳しい先生や博士課程の人にツッコミを受けながら読んでいけたのはめちゃくちゃ勉強になった。これだけで一年分の学費ペイする。
  • 研究テーマを考えるため、サーベイしてプロジェクトのアイデアを研究室の人や友人に発表して反応を見て...を繰り返していた。
  • 授業も楽しく過ごしています: 楽しかった授業
  • クォーター制は受ける側としては集中して勉強できるので嬉しい、英語講義は人によって良いのでけれど...英語苦手な先生だと資料を読み上げるだけになってしまうので厳しく、先生にも生徒にも辛い感じになってるなと思った

いったん休学

仕事が忙しくなりそうなので一旦次の2022年10月までは休学することにしました。この後のことは何も考えてない。


その他

ScalaMatsuri にスタッフで参加しました

scalamatsuri.org

  • 一般参加者として2018年から参加していた ScalaMatsuri に初めてスタッフとして参加しました。
    • 学会などと被ってしまい大きな貢献はできず申し訳無い :bow:
  • 今年は参加無料だったということもあり(?)とても多くの方が参加してくださり、(イベント会場として利用した)Discordもめちゃくちゃ大盛りあがりしており、1Scalaユーザーとしてイベントスタッフとしてもとても嬉し楽しかったです!

2日目のオープンマイクで metals の機能紹介をした結果、何人かに布教成功したようで嬉しい :tada:

scrapbox.io

Apex ソロダイヤ

うれし〜〜〜、プレイ時間は1000時間くらいです。

今シーズンは立ち回りさえ良ければ盛れる環境になっているらしく、次シーズンもダイヤに行けるのか不安...撃ち合いがそんなに強くない自覚はあるので最近はkovaakでエイムの練習したりしている。ジャンプマスターだけは任せてくれ。

Essential Effects を読んで Cats Effect を勉強した

Scala Advent Calendar 2021 1日目の記事です。

scala-cli のこと書こうと思ったのですが、ちょっと時間なかったので読書記です!

essentialeffects.dev

typelevel.org

TL;DR

  • Essential Effects という本を読んで
  • Cats Effect という、ScalaIO とか parallel and concurrent なプログラムを勉強したよ
  • とてもわかり易かったのでおすすめです、あと猫がかわいい

The Effect Pattern

Essential Effect 1章の話のメモ

この本ではまず初めに IO モナドを使って副作用をラップしてやることのメリットの解説から始まります。本の中では、そのようなプログラムの方法を Effect Pattern と呼んでおり(多分この本でしか言ってない?)、その principal は

The type of the program should tell us what kind of effects the program will perform, in addition to the type of the value it will produce.

  • 例えば println は、標準出力に引数に与えた値を出力するという副作用を起こす関数だが、そのシグネチャAny => Unit みたいな感じ
    • これだけ見ると何か副作用が起こるかどうかは分からない
  • Any => IO[Unit] ならば、Anyを受け取って、何か動作を行って、その結果として Unit 型の値を返す。ということがシグネチャから分かる。
    • といってもIOだと何かが起こる(何が起こるかは分からん)ので情報量はあまりないように思う。
    • eff とか使うといろんな作用がシグネチャに現れて楽しい気がしますね

If the behavior we want relies upon some externally-visible side effect, we separate describing the effects we want to happen from actually making them happen. We can freely substitute the description of effects until the point we run them

  • 副作用が実際に起こるのを遅延させられる。これにより IO#unsafeRun を実行するまでは副作用が起きないということが分かる
  • 何が嬉しい?
    • compose した effect の実行時エラーハンドリングなんかを、effects の実行部分でまとめられるところとかなのだろうか?

また、本の中ではこれを満たしていたら Effect だ!というチェックリストが書かれており(これは一般的な認識なんだろうか?この本の著者がこう言ってるだけ?)

    1. Does the type of the program tell us
      1. what kind of effects the program will perform; and
      1. what type of value it will produce?
    1. When externally-visible side effects are required, is the effect description separate from the execution?

Scala の Future は - 1 は満たす (a. Future は非同期実行ですよ、b. Future[T] なら T を produce するよ) - しかし、2は満たさない。Future の body は externally-visible side effects だが、その中身は Future が construct されたら即座に実行されるので

ということで Future ではなく cats-effectIO が登場するのであった...

演習問題がたくさん

上に書いたことを読むと理論よりの本のように思えるかも知れないが、演習問題が豊富で例えば以下のようなことが手を動かしながら学ぶことができる

  • IO モナドを自作してみたり
  • Resources を使って外部リソースの auto closing や combine などを試してみたり
  • Deferred を使って同時に実行する複数のエフェクト間の協調について学んだり
  • 著者が Concurrent State Machines と読んでいるパターンを使って(状態が外部から見えない)countdown latchを作ってみたり
  • cats-effect の parMapN という複数のIOをconcurrentに実行するメソッドを step by step で実装することにより、 cats-effect の fiber の fork, join, cancel の挙動を理解するなど
  • 総復習として job queue を作ってみたり
/** - ia と ib の computation を "concurrent" に実行する 
  *  - each result を wait
  *  - ia か ib が fail した場合は他方を cancel
  *  - 2つの結果を f で combine
  */ 
def myParMapN[A, B, C](ia: IO[A], ib: IO[B])(f: (A, B) => C): IO[C] = ???

まとめ

非常に良い本なので cats-effect に限らず IO を使った並列並行処理について学んでみたい人は是非読んでみてください。

著者のEssentialEffectsに関する発表が以下のYoutubeから見れるので興味ある人は見てみてね。

youtu.be

GSoC 2021 に参加して Scala3 の開発環境を改善させてもらった

2021/06 から参加していた Google Summer of Code 無事修了しました。

GSoC では Add synthetics and symbol information for semanticdb in Scala 3 という題目で Scala3 の IDE や Linter のための基盤となる機能の開発をしていました。

今回の成果により Scala3 でも Metals (Scala の Language Server 実装) で go-to-implementation, show-inferred-types, show-implicit-arguments (& context-params) などなどの機能が使えるようになる予定です。

f:id:tanishiking24:20210901193235p:plain

https://summerofcode.withgoogle.com/projects/#5527632738779136

採択されるまで

もともと趣味で土日の空いた時間に Metals の Scala3 サポートをちまちま進めていたのですが、せっかく学生なのだしGSoCを利用して数ヶ月の間フルタイムで Scala3 サポートの改善に取り組めないかと思い、GSoC で Scala の開発に取り組みたいと思い始めました。

Scala organization は 2018年までは GSoC に参加 していたのですが、残念ながらScala3の開発などで余力がなくここ数年の間はGSoCに参加していませんでした。

このままだと多分今年もScalaがGSoCに参加することはないなと思い、Metals の Scala3 サポートに取り組みたいんだけど GSoC 参加してくれたりしませんか?っていうことを Scala Center に対して問い合わせてみた。

contributors.scala-lang.org

すぐに前向きな返事が返ってきて、なんと3週間後にはGSoCに申し込みしたよとの連絡が!

本当にありがとうございます

すぐさま proposal を書き (今見ると結構ひどい...)

docs.google.com

応募したところ、これまでのScalaコミュニティへのOSSコントリビューションが評価されたのか無事採用されました。良かった。

期間中

全体のレポートはここにまとまています。

github.com

期間中は毎週金曜日にに30-40分ほどメンターと進捗確認と来週やること、提出したPRやissueについて Google meets で議論をする機会を頂いていました。メンターは主に二人で一人はポーランド(Krakow)、もうひとりはスイス(Lausanne)でふたりともUTC+02:00に住んでいて日本とは7時間の時差があったのですが、僕がわりと夜型だったこともあり特に問題なくスムーズにコミュニケーションをとることができました。(レビュアーの主な活動時間が日本時間での22:00-26:00とかだったので、その時間帯にレビューに返事するとほぼリアルタイムで議論で非同期コミュニケーションができて良い)

おわりに

GSoC の倍率は非常に高く、日本のアカデミックカレンダーでは授業期間とGSoC期間が丸かぶりしており参加のハードルが高いですが、著名なソフトウェアに対してある程度大規模の貢献をフルタイムで行える機会や、国内にいながら世界中のソフトウェアエンジニアと肩を並べて仕事をできる機会はなかなかなく、参加する価値は非常に大きいと思います。興味のある方は是非来年にでも申し込んでみてください。

GSoC 一般のことについては正直あまりアドバイスできないと思いますが、もし来年 Scala が GSoC に参加していて、Scala (の特に Tooling まわり) に対して貢献したいという方がいらっしゃれば是非Twitterか何かで声をかけてください。何かお手伝いできるかもしれません。

GSoCは終わってしまいましたが、scalameta や dotty や metals への貢献はこれからも続けて行く予定です。

ダメ元でGSoC参加したいな〜という話を投げた結果本当に参加できることになり本当に嬉しかったです、GSoC on Scala を実現してくれた皆さん本当にありがとうございました。 (日本語で書いても伝わらないけど...)

乞食

今後のOSS活動の活力になります。

www.amazon.jp