foxの集合型について

https://bitbucket.org/x768/fox-lang

foxの組み込みの集合型は以下のものがあります。

  • List: 配列
  • Map: 順序不定の連想配列
  • Set: 順序不定で重複なしの集合型
  • Range: 範囲型
puts typeof([])    // lang.List
puts typeof({})    // lang.Map
puts typeof(Set()) // lang.Set
puts typeof(1..3)  // lang.Range

配列への追加・削除は、JavaScriptと同じようなメソッドが使用できます。

let a = []
a.push 1, 2
a.unshift 3
puts a         // [3, 1, 2]
puts a.pop()   // 2
puts a.shift() // 3
puts a         // [1]

配列、連想配列は、jsonとほぼ同じ書き方ができます。

let json = {
  "array":[1, 2.5, true, false, null],
  "map":{"foo":100, "bar":200},
  "postal":"\u3020",
}

連想配列は、文字列型のキーの場合、以下の記法が使えます。

// 下の2つは同じ意味
let map1 = { foo = 100, bar = 200 }
let map2 = { "foo":100, "bar":200 }

// 下の2つは同じ意味
puts map1.foo    // 100
puts map1["foo"] // 100

forループで使用すると、各要素を巡回します。ただし、MapSetは順不定です。

for v in [1, 2, 3] {
  puts v
}
for v in {foo = 1, bar = 2} {
  puts v.key, ":", v.value
}
for v in Set(1, 2, 3) {
  puts v
}
for v in 0..3 {
  puts v  // 0 1 2
}

これらの型はIterableを継承しているため、様々な共通メソッドが使用できます。

// mapは、各要素に関数を適用した結果を返すイテレータを返す
for v in [1, 2, 3].map(i => i * 2) {
  puts v
}
for v in {foo = 100, bar = 200}.map(i => i.value * 2) {
  puts v
}
for v in Set(1, 2, 3).map(i => i * 2) {
  puts v
}
for v in (1..4).map(i => i * 2) {
  puts v
}

// joinは、各要素を文字列化して連結する
puts [1, 2, 3].join(",")     // 1,2,3
puts Set(1, 2, 3).join(",")  // 1,2,3 (順不定)
puts (1..4).join(",")        // 1,2,3

// selectは、条件に一致する要素を返すイテレータを返す
for v in [1, 2, 3, 4, 5].select(i => i % 2 == 0) {
  puts v  // 2 4
}

// sortは、全ての要素をソートした結果の配列を返す
// 比較関数が渡されていない場合は、デフォルトの比較関数が使われる
puts [2, 3, 1].sort()                // [1, 2, 3]
puts [2, 3, 1].sort((a, b) => b - a) // [3, 2, 1]
puts Set(2, 3, 1).sort()             // [1, 2, 3]

foxの数値型について

https://bitbucket.org/x768/fox-lang

foxの組み込み数値型は3種類あります。

puts typeof(1)    // lang.Int (整数型)
puts typeof(1.0)  // lang.Float (浮動小数点数)
puts typeof(1d)   // lang.Frac (有理数型)

違う型同士の演算はエラーとなるため、明示的に型を合わせる必要があります。

puts 1 + Int(1.0)   // 2
puts Float(1) + 1.0 // 2.0
puts 1 + 1.0        // TypeError

Int (整数型)

32bit整数を超える範囲は多倍長整数になりますが、どちらも区別なく扱えます。

puts 1234567890 * 1234567890

リテラルは、10進数、16進数と、2進数が使えます。

puts 0x1234_5678_90AB_CDEF
puts 0b1010_1101_1111_0000

加減乗除と、剰余演算が可能です。

Float (浮動小数点数)

IEEE754形式(倍精度)の浮動小数点数です。

puts 1.0    // 1.0
puts 1e+6   // 1000000.0

ゼロ除算はエラーになります。

puts 1.0 / 0.0   // ZeroDivisionError

Frac (有理数型)

内部的には、分子/分母 の形式で値を保持していますが、10進数の小数と同じように扱うことができます。

let f = 0.75d
puts f   // 0.75
puts f.numerator, '/', f.denominator  // 3/4

let f3 = Frac(1, 3)   // 1/3
puts f3       // 0.333333...
puts f3 * 3d  // 1.0

mathモジュールの関数を使うことで端数処理ができるので、JavaBigDecimalの代わりに使えます。

import math

puts round_floor(1.5d)       // 1.0
puts round_ceiling(-1.5d)    // -1.0
puts round_half_up(1.45)     // 1.0
puts round_half_up(1.45, 1)  // 1.5