【簡易版】CoffeeScriptにも型を!

## 0.はじめに

この文章は、筆者個人によって作成されたものであり、正確性や完全性を保証するものではありません。本文章を使用した結果、利用者が直接または間接的に被った損害については、筆者は一切の責任を負いかねます。利用者は、本文章を参考にするか否かを決定する際には自己責任を負う必要があります。また、筆者は予告なく本文章を変更することがあります。

## 1.目次

[0.はじめに](#0%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)
[1.目次](#1%E7%9B%AE%E6%AC%A1)
[2.目的](#2%E7%9B%AE%E7%9A%84)
[3.概要](#3%E6%A6%82%E8%A6%81)
[・連想配列と分割代入](#%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%A8%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5)
[・簡易版(`auto`関数)について](#%E7%B0%A1%E6%98%93%E7%89%88auto%E9%96%A2%E6%95%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
[4.動作確認](#4%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)
[5.コードを書いてみる](#5%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E3%81%BF%E3%82%8B)
[・ハローワールド(概要からの続き)](#%E3%83%8F%E3%83%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E6%A6%82%E8%A6%81%E3%81%8B%E3%82%89%E3%81%AE%E7%B6%9A%E3%81%8D)
[・絶対値を返す関数](#%E7%B5%B6%E5%AF%BE%E5%80%A4%E3%82%92%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0)
[・複数の引数を受ける関数](#%E8%A4%87%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%82%92%E5%8F%97%E3%81%91%E3%82%8B%E9%96%A2%E6%95%B0)
[・`map`メソッドで配列操作](#map%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A7%E9%85%8D%E5%88%97%E6%93%8D%E4%BD%9C)
[・引数の処理をまとめる](#%E5%BC%95%E6%95%B0%E3%81%AE%E5%87%A6%E7%90%86%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%82%8B)
[・関数テンプレート](#%E9%96%A2%E6%95%B0%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88)
[6.おわりに](#6%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB)

## 2.目的

JavaScriptをシンプルな記述で書くことができるaltJS(※)のCoffeeScriptでも型を使ってプログラミングしたい。

※alternative JavaScriptは、トランスパイル(変換)するとJavaScriptを出力する言語の総称、有名なものではMicrosoftのTypeScriptなど。

## 3.概要

JavaScriptをはじめとした多くのスクリプト言語は動的に型を利用してプログラミングを行う為、予期せぬ動作やエラーが起こる可能性があります。と言っても次のコードの何処かにバグがあるかはわかりません。

```coffeescript:通常の関数
show = (value) ->
  alert value
  return 

show "Hello,CoffeeScript!"
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:show%20%3D%20(value)%20-%3E%0A%20%20alert%20value%0A%20%20return%20%0A%0Ashow%20%22Hello%2CCoffeeScript!%22))([v1.12.7](https://coffeescript.org/v1/#try:show%20%3D%20(value)%20-%3E%0A%20%20alert%20value%0A%20%20return%20%0A%0Ashow%20%22Hello%2CCoffeeScript!%22))][[js2coffee](http://js2.coffee/#coffee/try:show%20%3D%20(value)%20-%3E%0A%20%20alert%20value%0A%20%20return%20%0A%0Ashow%20%22Hello%2CCoffeeScript!%22)]

そこで、変数などに入れる値は型情報を持っているので、それを元に連想配列を作り関数の引数に分割代入で渡した場合、関数の定義と異なった誤った型が混入することは無いかと思います。

```coffeescript:連想配列と分割代入を使用した関数
str = {string: "Hello,type safe?"}

show2 = ({string: s}) -> void:
  alert s

{void: result} = show2 str
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str))([v1.12.7](https://coffeescript.org/v1/#try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str))][[js2coffee](http://js2.coffee/#coffee/try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str)]

文字列の`string`や何も無い事を表す`void`が型に当たりますが、`show2`関数ではこの`void`を無視する処理を記述していないので返り値を`{void: result}`に念の為分割代入しています。

### ・連想配列と分割代入
連想配列は`key`要素と`value`値がペアになったデータの事です。
```coffeescript:連想配列
object = {key: "value"}

# CoffeeScriptは中括弧{}を省略出来ます
object = key: "value"

# 以下と同等
object = {} # 準備
object.key = "value"
object["key"] = "value"

# 例
user = {name: "Tarou"}
alert user.name # Tarou
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou))([v1.12.7](https://coffeescript.org/v1/#try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou))][[js2coffee](http://js2.coffee/#coffee/try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou)]

分割代入は、連想配列のキーの値を変数に代入する際に使用します。
```coffeescript:分割代入
{key: variable} = object

# 以下と同等
variable = object.key
variable = object["key"]

# 例
{name: result} = user
alert result # Tarou
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou%0A%0A%23%20%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5%0A%7Bkey%3A%20variable%7D%20%3D%20object%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Avariable%20%3D%20object.key%0Avariable%20%3D%20object%5B%22key%22%5D%0A%0A%23%20%E4%BE%8B%0A%7Bname%3A%20result%7D%20%3D%20user%0Aalert%20result%20%23%20Tarou))([v1.12.7](https://coffeescript.org/v1/#try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou%0A%0A%23%20%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5%0A%7Bkey%3A%20variable%7D%20%3D%20object%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Avariable%20%3D%20object.key%0Avariable%20%3D%20object%5B%22key%22%5D%0A%0A%23%20%E4%BE%8B%0A%7Bname%3A%20result%7D%20%3D%20user%0Aalert%20result%20%23%20Tarou))][[js2coffee](http://js2.coffee/#coffee/try:object%20%3D%20%7Bkey%3A%20%22value%22%7D%0A%0A%23%20CoffeeScript%E3%81%AF%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%92%E7%9C%81%E7%95%A5%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%0Aobject%20%3D%20key%3A%20%22value%22%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Aobject%20%3D%20%7B%7D%20%23%20%E6%BA%96%E5%82%99%0Aobject.key%20%3D%20%22value%22%0Aobject%5B%22key%22%5D%20%3D%20%22value%22%0A%0A%23%20%E4%BE%8B%0Auser%20%3D%20%7Bname%3A%20%22Tarou%22%7D%0Aalert%20user.name%20%23%20Tarou%0A%0A%23%20%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5%0A%7Bkey%3A%20variable%7D%20%3D%20object%0A%0A%23%20%E4%BB%A5%E4%B8%8B%E3%81%A8%E5%90%8C%E7%AD%89%0Avariable%20%3D%20object.key%0Avariable%20%3D%20object%5B%22key%22%5D%0A%0A%23%20%E4%BE%8B%0A%7Bname%3A%20result%7D%20%3D%20user%0Aalert%20result%20%23%20Tarou)]

### ・簡易版(`auto`関数)について
この文章で作成する`auto`関数は関数の定義で使用し、引数で与えられた連想配列を利用する関数を無名関数でラップして返します。

無名関数の内部では引数から連想配列を生成、生成した連想配列を内部の関数に渡して実行、返り値の連想配列から値を取り出して実行結果として返します。

無名関数でラップする事で、通常の関数と変わらない使用感を実現していると思います。

```coffeescript:auto関数の使い方
# usage: procedure value
procedure = auto ({type: variable}) -> type:
  # 〜何らかの処理〜
```

使用する型は`void`と`typeof`演算子で取得したもの(`string`、`number`、`boolean`、`function`、`object`、`symbol`、、、等々)を想定しており、自作のクラス等利用する時は`object`として取り扱うことになると思います。

関数の引数に指定した型以外の型を渡した場合のエラーを考慮していませんので、デフォルトの引数を使用しましょう(js2coffee非対応)。
```coffeescript:デフォルトの引数
# 通常の関数
# usage: procedure()
procedure = (variable = "value") ->
  # ～何らかの処理～

# 簡易版の関数
# usage: procedure()
procedure = auto ({type: variable = "value"} = {}) -> type:
  # ～何らかの処理～
```

また、関数内で複数の処理を記述したい場合は、連想配列を返す仕様の為、括弧()や`try～catch～`(もしくは、`if～else～`)で囲いましょう。
```coffeescript:複数の処理
# 引数なしの関数
procedure = auto -> type: (
  # ～何らかの処理1～
  # ～何らかの処理2～
)

procedure = auto -> type:
  try
    # ～何らかの処理1～
    # ～何らかの処理2～
  catch e
    # ～エラー処理～
```

## 4.動作確認
・公式(https://coffeescript.org) のTry CoffeeScript([v2.7.0](https://coffeescript.org/#try)、[v1.12.7](https://coffeescript.org/v1/#try))  
・js2coffee(http://js2.coffee) (CoffeeScript v1.9.2)  
・AndroidのTermuxアプリ(インストールの説明は省きます)にNode.js(v19.4.0)、CoffeeScript(v2.5.1)をインストール

※js2coffeeは横向きにしないとコードの画面になりませんでした。もし表示されない場合は、画面は自動回転に設定しておきましょう(スマホ、タブレットの方)

## 5.コードを書いてみる

### ・ハローワールド(概要からの続き)

~~キーをいちいち書くのがなんとも言えないので、~~
値から`typeof`でキーを取得して連想配列を生成(`pack`関数)。

```coffeescript:pack関数
# 値を連想配列に詰める関数
# キーは値の型
pack = (value) ->
  {"#{typeof value}": value}

show2 pack "Hello,type safe!?"
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str%0A%0A%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0Ashow2%20pack%20%22Hello%2Ctype%20safe!%3F%22))([v1.12.7](https://coffeescript.org/v1/#try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str%0A%0A%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0Ashow2%20pack%20%22Hello%2Ctype%20safe!%3F%22))][[js2coffee](http://js2.coffee/#coffee/try:str%20%3D%20%7Bstring%3A%20%22Hello%2Ctype%20safe%3F%22%7D%0A%0Ashow2%20%3D%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0A%7Bvoid%3A%20result%7D%20%3D%20show2%20str%0A%0A%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0Ashow2%20pack%20%22Hello%2Ctype%20safe!%3F%22)]

連想配列から中の値を取り出す(`unpack`関数)。
```coffeescript:unpack関数
# 連想配列から値を取り出す関数。voidは無視
unpack = (obj) ->
  for key, value of obj
    if key is "void"
      return
    else if typeof value is key
      return value
    else
      throw new Error
```
関数を受け取り自動化(引数`pack`/関数実行/返り値`unpack`)する関数を返す(`auto`関数)。
```coffeescript:auto関数
# 連想配列を受け取って返す関数を無名関数内で実行するように
# 無名関数は引数の値をpackして引数の関数へ、返り値をunpackして返す
auto = (proc) ->
  (param) ->
    result = proc pack param
    unpack result
```

```coffeescript:文字列を出力する関数
show3 = auto ({string: s}) -> void:
  alert s

show3 "Hello,world!"
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0Ashow3%20%3D%20auto%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow3%20%22Hello%2Cworld!%22))([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0Ashow3%20%3D%20auto%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow3%20%22Hello%2Cworld!%22))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0Ashow3%20%3D%20auto%20(%7Bstring%3A%20s%7D)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow3%20%22Hello%2Cworld!%22)]

すっきり書けます(が、環境によっては`auto`を関数を入れる変数と関数の定義の間に書くとコードの色分けが効かなくなるみたいです)。
```coffeescript:文字列を出力する関数(js2coffee)
# CoffeeScript v1.9.2(どのバージョンまでいけるか未調査)では
# 関数の引数の中括弧{}も省略して更にすっきり
show4 = auto (string: s) -> void:
  alert s

show4 "Hello,world in v1"
```
[Try CoffeeScript(~~[v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20CoffeeScript%20v1.9.2(%E3%81%A9%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%BE%E3%81%A7%E3%81%84%E3%81%91%E3%82%8B%E3%81%8B%E6%9C%AA%E8%AA%BF%E6%9F%BB)%E3%81%A7%E3%81%AF%0A%23%20%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AE%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%82%E7%9C%81%E7%95%A5%E3%81%97%E3%81%A6%E6%9B%B4%E3%81%AB%E3%81%99%E3%81%A3%E3%81%8D%E3%82%8A%0Ashow4%20%3D%20auto%20(string%3A%20s)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow4%20%22Hello%2Cworld%20in%20v1%22)~~)(~~[v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20CoffeeScript%20v1.9.2(%E3%81%A9%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%BE%E3%81%A7%E3%81%84%E3%81%91%E3%82%8B%E3%81%8B%E6%9C%AA%E8%AA%BF%E6%9F%BB)%E3%81%A7%E3%81%AF%0A%23%20%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AE%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%82%E7%9C%81%E7%95%A5%E3%81%97%E3%81%A6%E6%9B%B4%E3%81%AB%E3%81%99%E3%81%A3%E3%81%8D%E3%82%8A%0Ashow4%20%3D%20auto%20(string%3A%20s)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow4%20%22Hello%2Cworld%20in%20v1%22)~~)][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20CoffeeScript%20v1.9.2(%E3%81%A9%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%BE%E3%81%A7%E3%81%84%E3%81%91%E3%82%8B%E3%81%8B%E6%9C%AA%E8%AA%BF%E6%9F%BB)%E3%81%A7%E3%81%AF%0A%23%20%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AE%E4%B8%AD%E6%8B%AC%E5%BC%A7%7B%7D%E3%82%82%E7%9C%81%E7%95%A5%E3%81%97%E3%81%A6%E6%9B%B4%E3%81%AB%E3%81%99%E3%81%A3%E3%81%8D%E3%82%8A%0Ashow4%20%3D%20auto%20(string%3A%20s)%20-%3E%20void%3A%0A%20%20alert%20s%0A%0Ashow4%20%22Hello%2Cworld%20in%20v1%22)]

### ・絶対値を返す関数
ハローワールドだけでは寂しいので別の関数が動くか確認。
```coffeescript:abs関数
# numberを受け取ってnumberを返す関数
abs = auto ({number: n}) -> number:
  if n < 0
    -n
  else
    n

alert abs -1 # 1
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20number%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6number%E3%82%92%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%0Aabs%20%3D%20auto%20(%7Bnumber%3A%20n%7D)%20-%3E%20number%3A%0A%20%20if%20n%20%3C%200%0A%20%20%20%20-n%0A%20%20else%0A%20%20%20%20n%0A%0Aalert%20abs%20-1%20%23%201))([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20number%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6number%E3%82%92%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%0Aabs%20%3D%20auto%20(%7Bnumber%3A%20n%7D)%20-%3E%20number%3A%0A%20%20if%20n%20%3C%200%0A%20%20%20%20-n%0A%20%20else%0A%20%20%20%20n%0A%0Aalert%20abs%20-1%20%23%201))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%E3%82%92%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E5%86%85%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%0A%23%20%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%E3%81%AF%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92pack%E3%81%97%E3%81%A6%E5%BC%95%E6%95%B0%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%B8%E3%80%81%E8%BF%94%E3%82%8A%E5%80%A4%E3%82%92unpack%E3%81%97%E3%81%A6%E8%BF%94%E3%81%99%0Aauto%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%0A%23%20number%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6number%E3%82%92%E8%BF%94%E3%81%99%E9%96%A2%E6%95%B0%0Aabs%20%3D%20auto%20(%7Bnumber%3A%20n%7D)%20-%3E%20number%3A%0A%20%20if%20n%20%3C%200%0A%20%20%20%20-n%0A%20%20else%0A%20%20%20%20n%0A%0Aalert%20abs%20-1%20%23%201)]

-1を渡して1が返ってきました。

### ・複数の引数を受ける関数
2つの数を足した値を返す関数を`auto`関数に渡さずに書いてみます。
```coffeescript:add関数
# 引数を2つ受ける場合の記述の確認
add = ({number: x}, {number: y}) -> number: x + y
{number: result} = add {number: 1}, {number: 2}
alert result # 3
```
```coffeescript:add2関数
add2 = ([{number: x}, {number: y}]) -> number: x + y
{number: result} = add2 [{number: 3}, {number: 4}]
alert result # 7
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%BC%95%E6%95%B0%E3%82%922%E3%81%A4%E5%8F%97%E3%81%91%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E8%A8%98%E8%BF%B0%E3%81%AE%E7%A2%BA%E8%AA%8D%0Aadd%20%3D%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add%20%7Bnumber%3A%201%7D%2C%20%7Bnumber%3A%202%7D%0Aalert%20result%20%23%203%0A%0Aadd2%20%3D%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add2%20%5B%7Bnumber%3A%203%7D%2C%20%7Bnumber%3A%204%7D%5D%0Aalert%20result%20%23%207))([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%BC%95%E6%95%B0%E3%82%922%E3%81%A4%E5%8F%97%E3%81%91%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E8%A8%98%E8%BF%B0%E3%81%AE%E7%A2%BA%E8%AA%8D%0Aadd%20%3D%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add%20%7Bnumber%3A%201%7D%2C%20%7Bnumber%3A%202%7D%0Aalert%20result%20%23%203%0A%0Aadd2%20%3D%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add2%20%5B%7Bnumber%3A%203%7D%2C%20%7Bnumber%3A%204%7D%5D%0Aalert%20result%20%23%207))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%BC%95%E6%95%B0%E3%82%922%E3%81%A4%E5%8F%97%E3%81%91%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E8%A8%98%E8%BF%B0%E3%81%AE%E7%A2%BA%E8%AA%8D%0Aadd%20%3D%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add%20%7Bnumber%3A%201%7D%2C%20%7Bnumber%3A%202%7D%0Aalert%20result%20%23%203%0A%0Aadd2%20%3D%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0A%7Bnumber%3A%20result%7D%20%3D%20add2%20%5B%7Bnumber%3A%203%7D%2C%20%7Bnumber%3A%204%7D%5D%0Aalert%20result%20%23%207)]

`auto`関数は複数の引数に対応していないので修正します。
`add`関数のように書きたいですが`add2`関数のように`Array`を利用します。引数が配列だった場合、配列の各要素を取り出して連想配列にパックして配列に詰め直します。
```coffeescript:auto2関数
# 修正版
auto2 = (proc) ->
  (param) ->
    if param instanceof Array
      params = []
      for i in [0..param.length-1]
        params[i] = pack param[i]
      result = proc params
    else
      result = proc pack param
    unpack result
```

```coffeescript:add3関数
add3 = auto2 ([{number: x}, {number: y}]) -> number: x + y
alert add3 [5, 6] # 11
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%C2%A0%20%C2%A0%20%C2%A0%0A%23%20%E4%BF%AE%E6%AD%A3%E7%89%88%0Aauto2%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20if%20param%20instanceof%20Array%0A%20%20%20%20%20%20params%20%3D%20%5B%5D%0A%20%20%20%20%20%20for%20i%20in%20%5B0..param.length-1%5D%0A%20%20%20%20%20%20%20%20params%5Bi%5D%20%3D%20pack%20param%5Bi%5D%0A%20%20%20%20%20%20result%20%3D%20proc%20params%0A%20%20%20%20else%0A%20%20%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%20%C2%A0%20%C2%A0%0Aadd3%20%3D%20auto2%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add3%20%5B5%2C%206%5D%20%23%2011))([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%C2%A0%20%C2%A0%20%C2%A0%0A%23%20%E4%BF%AE%E6%AD%A3%E7%89%88%0Aauto2%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20if%20param%20instanceof%20Array%0A%20%20%20%20%20%20params%20%3D%20%5B%5D%0A%20%20%20%20%20%20for%20i%20in%20%5B0..param.length-1%5D%0A%20%20%20%20%20%20%20%20params%5Bi%5D%20%3D%20pack%20param%5Bi%5D%0A%20%20%20%20%20%20result%20%3D%20proc%20params%0A%20%20%20%20else%0A%20%20%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%20%C2%A0%20%C2%A0%0Aadd3%20%3D%20auto2%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add3%20%5B5%2C%206%5D%20%23%2011))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%C2%A0%20%C2%A0%20%C2%A0%0A%23%20%E4%BF%AE%E6%AD%A3%E7%89%88%0Aauto2%20%3D%20(proc)%20-%3E%0A%20%20(param)%20-%3E%0A%20%20%20%20if%20param%20instanceof%20Array%0A%20%20%20%20%20%20params%20%3D%20%5B%5D%0A%20%20%20%20%20%20for%20i%20in%20%5B0..param.length-1%5D%0A%20%20%20%20%20%20%20%20params%5Bi%5D%20%3D%20pack%20param%5Bi%5D%0A%20%20%20%20%20%20result%20%3D%20proc%20params%0A%20%20%20%20else%0A%20%20%20%20%20%20result%20%3D%20proc%20pack%20param%0A%20%20%20%20unpack%20result%0A%20%C2%A0%20%C2%A0%0Aadd3%20%3D%20auto2%20(%5B%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D%5D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add3%20%5B5%2C%206%5D%20%23%2011)]

引数が2つになってもちゃんと動いてますね。

### ・`map`メソッドで配列操作
ところで、おわりにも書きましたが、`auto2`関数にて`for〜in〜`の範囲指定で`[0..param.length-1]`の`-1`を打ち忘れて、配列の範囲外を参照しようとしてしまうという誤りがありました。単純なミスなので防ぎたいです。

部分配列の表現には、ピリオドを2つ`..`の他にも3つ`...`書く方法があり、`[0..n-1]`という記述は`[0...n]`のように書けますが、今度はピリオドを忘れてしまうかもしれませんので、別のやり方にします。

実は、`Array`オブジェクトは`map`という便利なメソッド(他にも`forEach`、`filter`、`sort`、`reduce`、`find`、、、等々)を持っていて、引数の関数に各要素を渡して処理し、新たな`Array`オブジェクトを返します。

```coffeescript:配列操作の比較
array = [0..4]
for i in [0..array.length-1] # or [0...array.length]
  array[i] += 1 # or array[i] = array[i] + 1
alert array # 1, 2, 3, 4, 5  

array2 = [5..9].map (value) -> value + 1
alert array2 # 6, 7, 8, 9, 10
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:array%20%3D%20%5B0..4%5D%0Afor%20i%20in%20%5B0..array.length-1%5D%0A%20%20array%5Bi%5D%20%2B%3D%201%20%23%20or%20array%5Bi%5D%20%3D%20array%5Bi%5D%20%2B%201%0Aalert%20array%20%23%201%2C%202%2C%203%2C%204%2C%205%20%20%0A%0Aarray2%20%3D%20%5B5..9%5D.map%20(value)%20-%3E%20value%20%2B%201%0Aalert%20array2%20%23%206%2C%207%2C%208%2C%209%2C%2010))([v1.12.7](https://coffeescript.org/v1/#try:array%20%3D%20%5B0..4%5D%0Afor%20i%20in%20%5B0..array.length-1%5D%0A%20%20array%5Bi%5D%20%2B%3D%201%20%23%20or%20array%5Bi%5D%20%3D%20array%5Bi%5D%20%2B%201%0Aalert%20array%20%23%201%2C%202%2C%203%2C%204%2C%205%20%20%0A%0Aarray2%20%3D%20%5B5..9%5D.map%20(value)%20-%3E%20value%20%2B%201%0Aalert%20array2%20%23%206%2C%207%2C%208%2C%209%2C%2010))][[js2coffee](http://js2.coffee/#coffee/try:array%20%3D%20%5B0..4%5D%0Afor%20i%20in%20%5B0..array.length-1%5D%0A%20%20array%5Bi%5D%20%2B%3D%201%20%23%20or%20array%5Bi%5D%20%3D%20array%5Bi%5D%20%2B%201%0Aalert%20array%20%23%201%2C%202%2C%203%2C%204%2C%205%20%20%0A%0Aarray2%20%3D%20%5B5..9%5D.map%20(value)%20-%3E%20value%20%2B%201%0Aalert%20array2%20%23%206%2C%207%2C%208%2C%209%2C%2010)]

`for〜in〜`と比べるとシンプルな記述ですね。さっそく`auto`関数に反映させます。

```coffeescript:auto3関数
# 再修正版
auto3 = (proc) ->
  (param) ->
    if param instanceof Array
      params = param.map (value) ->
        pack value
      result = proc params
    else
      result = proc pack param
    unpack result
```

さて、引数に関数を受け取り、戻り値(もしくは、関数)を返す関数の事を関数型プログラミングと呼ばれている世界では、高階関数と呼ぶそうです。

関数型プログラミングは、読んで字の如く関数を組み合わせる事でプログラミングを行っていくものですが、制限する(引数の値を変更しない、関数の外側に影響を与えない)事で副作用の無い安全なプログラミングを行い、バグを減らす事が出来ると思います。

### ・引数の処理をまとめる
引数が一つと複数の場合で、処理が別れていたのでまとめます(これで`pack`し忘れる事は無くなるはず)。

引数を受け取る`param`変数の後にピリオドを3つ`...`で可変長引数になります。ピリオドは、`...param`のようにも打てますが、v2しか対応していないようです。

関数に引数を渡す際は、`Function`オブジェクトの`apply`メソッドの第2引数に配列を指定する事で、順番通りに関数に引数を渡す事が出来ます。また、第1引数には関数内の`this`に割り当てたいオブジェクトを指定し、`null`/`undefined`の場合、グローバルオブジェクトになります。

`Function`オブジェクトには、他にも`call`メソッドもあり、第1引数は同じですが、関数に渡す引数が配列の場合、`proc.call null, array...`と記述します。

```coffeescript:auto4関数
# 可変長引数版
auto4 = (proc) ->
  (param...) ->
    params = param.map (value) -> pack value 
    result = proc.apply null, params
    unpack result
```
```coffeescript:add4関数
add4 = auto4 ({number: x}, {number: y}) -> number: x + y
alert add4 5, 6 # 11
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0Aadd4%20%3D%20auto4%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add4%205%2C%206%20%23%2011))([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0Aadd4%20%3D%20auto4%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add4%205%2C%206%20%23%2011))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0Aadd4%20%3D%20auto4%20(%7Bnumber%3A%20x%7D%2C%20%7Bnumber%3A%20y%7D)%20-%3E%20number%3A%20x%20%2B%20y%0Aalert%20add4%205%2C%206%20%23%2011)]

### ・関数テンプレート
関数の雛型を作り、型パラメータを自由に変えることで汎用性の高い関数を作ることが出来ます。

※ES2015(ES6)オブジェクトの定義時の`[]`内で変数の展開を行っている為、v2のみ動作になります(どうしてもv1で動かしたい場合は、`[]`の代わりに`"#{}"`を使用しましょう)。

`<>`ダイヤモンド演算子は無いので、外側に型パラメータ用の関数を用意します。

外側の関数から受け取った`typename`を、内側の雛型になる関数の型(引数、返り値)に適用させます。

```coffeescript:template関数
# 関数テンプレート
template = auto4 ({string: typename}) -> function:
  auto4 ({[typename]: t}) -> [typename]: t

alert template("number") 1 # 1
```
[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%E9%96%A2%E6%95%B0%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%0Atemplate%20%3D%20auto4%20(%7Bstring%3A%20typename%7D)%20-%3E%20function%3A%0A%20%20auto4%20(%7B%5Btypename%5D%3A%20t%7D)%20-%3E%20%5Btypename%5D%3A%20t%0A%0Aalert%20template(%22number%22)%201%20%23%201))]

```coffeescript:template2関数
# []→"#{}"に変更
template2 = auto4 ({string: typename}) -> function:
  auto4 ({"#{typename}": t}) -> "#{typename}": t

alert template2("number") 1 # 1
```

[Try CoffeeScript([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%5B%5D%E2%86%92%22%23%7B%7D%22%E3%81%AB%E5%A4%89%E6%9B%B4%0Atemplate2%20%3D%20auto4%20(%7Bstring%3A%20typename%7D)%20-%3E%20function%3A%0A%20%20auto4%20(%7B%22%23%7Btypename%7D%22%3A%20t%7D)%20-%3E%20%22%23%7Btypename%7D%22%3A%20t%0A%0Aalert%20template2(%22number%22)%201%20%23%201))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%5B%5D%E2%86%92%22%23%7B%7D%22%E3%81%AB%E5%A4%89%E6%9B%B4%0Atemplate2%20%3D%20auto4%20(%7Bstring%3A%20typename%7D)%20-%3E%20function%3A%0A%20%20auto4%20(%7B%22%23%7Btypename%7D%22%3A%20t%7D)%20-%3E%20%22%23%7Btypename%7D%22%3A%20t%0A%0Aalert%20template2(%22number%22)%201%20%23%201)]

関数名は置いておくとして、型パラメータが文字列であったりイマイチな感じですので、ちょっと遊んでみます。

```coffeescript:template修飾子もどき、型パラメータ関数の変更等
# 連鎖比較を利用したtemplate修飾子(ただの飾り)
# (複数の型を使う時はtemplate<T|U|V>、<T&U&V>のように)
template = 0
T = U = V =  1

# 型パラメータを受け取る関数を通常の関数にして
# typenameキーを持った連想配列を受け取るように変更
template<T> add5 = ({typename: T}) ->
  auto4 ({[T]: x}, {[T]: y}) -> [T]: x + y

# 型パラメータの構造に合わせて連想配列を作る
# 型の構造
types =
  number: {typename: "number"}

# 型を追加
# string, boolean, function, object, bigint, symbol
["", true, (->), {}, 1n, Symbol()]
  .forEach (value) ->
    name = typeof value
    types[name] = {typename: name}

# with風関数
# 外側の関数に、内側の関数の引数のprocのthisに割り当てたいobjを指定する
using = (obj) -> (proc) -> proc.call obj

using(types) ->
  alert add5(@number) 1, 2 # 3
  alert add5(@string) "1", "2" # 12
```

[Try CoffeeScript([v2.7.0](https://coffeescript.org/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%E9%80%A3%E9%8E%96%E6%AF%94%E8%BC%83%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9Ftemplate%E4%BF%AE%E9%A3%BE%E5%AD%90(%E3%81%9F%E3%81%A0%E3%81%AE%E9%A3%BE%E3%82%8A)%0A%23%20(%E8%A4%87%E6%95%B0%E3%81%AE%E5%9E%8B%E3%82%92%E4%BD%BF%E3%81%86%E6%99%82%E3%81%AFtemplate%3CT%7CU%7CV%3E%E3%80%81%3CT%26U%26V%3E%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB)%0Atemplate%20%3D%200%0AT%20%3D%20U%20%3D%20V%20%3D%20%201%0A%0A%23%20%E5%9E%8B%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B%E9%96%A2%E6%95%B0%E3%82%92%E9%80%9A%E5%B8%B8%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AB%E3%81%97%E3%81%A6%0A%23%20typename%E3%82%AD%E3%83%BC%E3%82%92%E6%8C%81%E3%81%A3%E3%81%9F%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E5%A4%89%E6%9B%B4%0Atemplate%3CT%3E%20add5%20%3D%20(%7Btypename%3A%20T%7D)%20-%3E%0A%20%20auto4%20(%7B%5BT%5D%3A%20x%7D%2C%20%7B%5BT%5D%3A%20y%7D)%20-%3E%20%5BT%5D%3A%20x%20%2B%20y%0A%0A%23%20%E5%9E%8B%E3%81%AE%E6%A7%8B%E9%80%A0%0Atypes%20%3D%0A%20%20number%3A%20%7Btypename%3A%20%22number%22%7D%0A%0A%23%20%E5%9E%8B%E3%82%92%E8%BF%BD%E5%8A%A0%0A%23%20string%2C%20boolean%2C%20function%2C%20object%2C%20bigint%2C%20symbol%0A%5B%22%22%2C%20true%2C%20(-%3E)%2C%20%7B%7D%2C%201n%2C%20Symbol()%5D%0A%20%20.forEach%20(value)%20-%3E%0A%20%20%20%20name%20%3D%20typeof%20value%0A%20%20%20%20types%5Bname%5D%20%3D%20%7Btypename%3A%20name%7D%0A%0A%23%20with%E9%A2%A8%E9%96%A2%E6%95%B0%0A%23%20%E5%A4%96%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AB%E3%80%81%E5%86%85%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AEproc%E3%81%AEthis%E3%81%AB%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%81%9F%E3%81%84obj%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B%0Ausing%20%3D%20(obj)%20-%3E%20(proc)%20-%3E%20proc.call%20obj%0A%0Ausing(types)%20-%3E%0A%20%20alert%20add5(%40number)%201%2C%202%20%23%203%0A%20%20alert%20add5(%40string)%20%221%22%2C%20%222%22%20%23%2012))]

```coffeescript:v1で動作するように修正

# 〜 省略 〜

# []→"#{}"に変更
template<T> add6 = ({typename: T}) ->
  auto4 ({"#{T}": x}, {"#{T}": y}) -> "#{T}": x + y

# 〜 省略 〜

# bigint型ES2020を削除
# string, boolean, function, object, symbol
["", true, (->), {}, Symbol()]
  .forEach (value) ->
    name = typeof value
    types[name] = {typename: name}

# 〜 省略 〜

# 関数名、引数の値を変更
using(types) ->
  alert add6(@number) 3, 4 # 7
  alert add6(@string) "3", "4" # 34
```

[Try CoffeeScript([v1.12.7](https://coffeescript.org/v1/#try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%E9%80%A3%E9%8E%96%E6%AF%94%E8%BC%83%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9Ftemplate%E4%BF%AE%E9%A3%BE%E5%AD%90(%E3%81%9F%E3%81%A0%E3%81%AE%E9%A3%BE%E3%82%8A)%0A%23%20(%E8%A4%87%E6%95%B0%E3%81%AE%E5%9E%8B%E3%82%92%E4%BD%BF%E3%81%86%E6%99%82%E3%81%AFtemplate%3CT%7CU%7CV%3E%E3%80%81%3CT%26U%26V%3E%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB)%0Atemplate%20%3D%200%0AT%20%3D%20U%20%3D%20V%20%3D%20%201%0A%0A%23%20%5B%5D%E2%86%92%22%23%7B%7D%22%E3%81%AB%E5%A4%89%E6%9B%B4%0Atemplate%3CT%3E%20add6%20%3D%20(%7Btypename%3A%20T%7D)%20-%3E%0A%20%20auto4%20(%7B%22%23%7BT%7D%22%3A%20x%7D%2C%20%7B%22%23%7BT%7D%22%3A%20y%7D)%20-%3E%20%22%23%7BT%7D%22%3A%20x%20%2B%20y%0A%0A%23%20%E5%9E%8B%E3%81%AE%E6%A7%8B%E9%80%A0%0Atypes%20%3D%0A%20%20number%3A%20%7Btypename%3A%20%22number%22%7D%0A%0A%23%20bigint%E5%9E%8BES2020%E3%82%92%E5%89%8A%E9%99%A4%0A%23%20string%2C%20boolean%2C%20function%2C%20object%2C%20symbol%0A%5B%22%22%2C%20true%2C%20(-%3E)%2C%20%7B%7D%2C%20Symbol()%5D%0A%20%20.forEach%20(value)%20-%3E%0A%20%20%20%20name%20%3D%20typeof%20value%0A%20%20%20%20types%5Bname%5D%20%3D%20%7Btypename%3A%20name%7D%0A%0A%23%20with%E9%A2%A8%E9%96%A2%E6%95%B0%0A%23%20%E5%A4%96%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AB%E3%80%81%E5%86%85%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AEproc%E3%81%AEthis%E3%81%AB%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%81%9F%E3%81%84obj%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B%0Ausing%20%3D%20(obj)%20-%3E%20(proc)%20-%3E%20proc.call%20obj%0A%0A%23%20%E9%96%A2%E6%95%B0%E5%90%8D%E3%80%81%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92%E5%A4%89%E6%9B%B4%0Ausing(types)%20-%3E%0A%20%20alert%20add6(%40number)%203%2C%204%20%23%207%0A%20%20alert%20add6(%40string)%20%223%22%2C%20%224%22%20%23%2034))][[js2coffee](http://js2.coffee/#coffee/try:%23%20%E5%80%A4%E3%82%92%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%AB%E8%A9%B0%E3%82%81%E3%82%8B%E9%96%A2%E6%95%B0%0A%23%20%E3%82%AD%E3%83%BC%E3%81%AF%E5%80%A4%E3%81%AE%E5%9E%8B%0Apack%20%3D%20(value)%20-%3E%0A%20%20%7B%22%23%7Btypeof%20value%7D%22%3A%20value%7D%0A%20%C2%A0%0A%23%20%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E9%96%A2%E6%95%B0%E3%80%82void%E3%81%AF%E7%84%A1%E8%A6%96%0Aunpack%20%3D%20(obj)%20-%3E%0A%20%20for%20key%2C%20value%20of%20obj%0A%20%20%20%20if%20key%20is%20%22void%22%0A%20%20%20%20%20%20return%0A%20%20%20%20else%20if%20typeof%20value%20is%20key%0A%20%20%20%20%20%20return%20value%0A%20%20%20%20else%0A%20%20%20%20%20%20throw%20new%20Error%0A%20%20%20%20%20%20%0A%23%20%E5%8F%AF%E5%A4%89%E9%95%B7%E5%BC%95%E6%95%B0%E7%89%88%0Aauto4%20%3D%20(proc)%20-%3E%0A%20%20(param...)%20-%3E%0A%20%20%20%20params%20%3D%20param.map%20(value)%20-%3E%20pack%20value%20%0A%20%20%20%20result%20%3D%20proc.apply%20null%2C%20params%0A%20%20%20%20unpack%20result%0A%0A%23%20%E9%80%A3%E9%8E%96%E6%AF%94%E8%BC%83%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9Ftemplate%E4%BF%AE%E9%A3%BE%E5%AD%90(%E3%81%9F%E3%81%A0%E3%81%AE%E9%A3%BE%E3%82%8A)%0A%23%20(%E8%A4%87%E6%95%B0%E3%81%AE%E5%9E%8B%E3%82%92%E4%BD%BF%E3%81%86%E6%99%82%E3%81%AFtemplate%3CT%7CU%7CV%3E%E3%80%81%3CT%26U%26V%3E%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB)%0Atemplate%20%3D%200%0AT%20%3D%20U%20%3D%20V%20%3D%20%201%0A%0A%23%20%5B%5D%E2%86%92%22%23%7B%7D%22%E3%81%AB%E5%A4%89%E6%9B%B4%0Atemplate%3CT%3E%20add6%20%3D%20(%7Btypename%3A%20T%7D)%20-%3E%0A%20%20auto4%20(%7B%22%23%7BT%7D%22%3A%20x%7D%2C%20%7B%22%23%7BT%7D%22%3A%20y%7D)%20-%3E%20%22%23%7BT%7D%22%3A%20x%20%2B%20y%0A%0A%23%20%E5%9E%8B%E3%81%AE%E6%A7%8B%E9%80%A0%0Atypes%20%3D%0A%20%20number%3A%20%7Btypename%3A%20%22number%22%7D%0A%0A%23%20bigint%E5%9E%8BES2020%E3%82%92%E5%89%8A%E9%99%A4%0A%23%20string%2C%20boolean%2C%20function%2C%20object%2C%20symbol%0A%5B%22%22%2C%20true%2C%20(-%3E)%2C%20%7B%7D%2C%20Symbol()%5D%0A%20%20.forEach%20(value)%20-%3E%0A%20%20%20%20name%20%3D%20typeof%20value%0A%20%20%20%20types%5Bname%5D%20%3D%20%7Btypename%3A%20name%7D%0A%0A%23%20with%E9%A2%A8%E9%96%A2%E6%95%B0%0A%23%20%E5%A4%96%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AB%E3%80%81%E5%86%85%E5%81%B4%E3%81%AE%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AEproc%E3%81%AEthis%E3%81%AB%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%81%9F%E3%81%84obj%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B%0Ausing%20%3D%20(obj)%20-%3E%20(proc)%20-%3E%20proc.call%20obj%0A%0A%23%20%E9%96%A2%E6%95%B0%E5%90%8D%E3%80%81%E5%BC%95%E6%95%B0%E3%81%AE%E5%80%A4%E3%82%92%E5%A4%89%E6%9B%B4%0Ausing(types)%20-%3E%0A%20%20alert%20add6(%40number)%203%2C%204%20%23%207%0A%20%20alert%20add6(%40string)%20%223%22%2C%20%224%22%20%23%2034)]

## 6.おわりに
最後まで読んで頂きありがとうございます。このような技術文書を書くのは(…そもそも何か書き残すことすら)初めてでしたがとても大変だという事がわかりました。

いろいろと勉強不足な点も多く、リテラルが欲しいところで初期化してない変数を書いていたり、些細な事ですが関数名の命名に悩みました。

間違いなどありましたらコメントなど頂けると助かります(と書きつつさっそく`auto2`関数の`[0..param.length-1]`の`-1`が抜けていました、、、2月中旬頃から書き始めて1ヶ月以上気が付かないなんて)。

更に`auto2`及び`auto3`関数の記述に抜けがありました。引数が配列でない場合の`param`を`pack`していないというミスでした、、、申し訳ありません。

さて、完全ではありませんが型を手に入れたCoffeeScriptに敵は、、、素晴らしいCoffeeScriptに栄光あれ!