
.NETã䜿çšããŠãã人ã¯ãããããCLRã®æ±çšæ©èœããã°ã©ãã³ã°èšèªã§ããFïŒãèããããšãããã§ãããã .NETã³ãã¥ããã£ä»¥å€ã®ããã°ã©ããŒã¯ãHaskellèšèªã«é¢é£ããé¢æ°åããã°ã©ãã³ã°ãç¥ã£ãŠããå¯èœæ§ãé«ãã§ãã
ãããã«ãããå€ãã®äººã䌌ããããªèšèªã奜ããšæããŸãããJVMã«ã¯é«åºŠãªããŒã«ããããæ©èœçãªã¹ã¿ã€ã«ã§ãã¹ãŠãè¡ãå¿ èŠã¯ãããŸããã
JetBrainsã® KotlinèšèªïŒ kotlinlang.org ïŒã¯ãJavaã®çããã®ã®ããã«èŠãããããããŸããïŒæ§æèŠåãåæšè«ãªã©ã ãããããã®åçŽãªã·ã§ã«ã®äžã§ã¯ãé¢æ°åèšèªã®æãäžè¬çã§é²æ©çãªæ§æããã¹ãŠèŠã€ããããšãã§ããŸãã
å žåçãªæ©èœæ§æã®ç°¡åãªäŸããå§ããŸãããã
代æ°ããŒã¿å
ãã®æ§æã¯ãã»ãšãã©ã®æ©èœèšèªã®éåžžã«å žåçãªãã®ã§ãã
data Maybe a = Nothing | Just a deriving (Eq, Ord)
ããã¯Haskellã§ãããMaybeåãå®çŸ©ãããŠããŸãããã®åã«ã¯ãNothingãšJustã®2ã€ã®ã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãã Justã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãæªå®çŸ©ã®åã®åäžã®ãã©ã¡ãŒã¿ãŒãåãå ¥ããŸãã ã掟çãããŒã¯ãŒãã¯ãã¿ã€ããªããžã§ã¯ããæ¯èŒããçãããã©ããããã§ãã¯ããããã®ã³ãŒããèªåçã«çæããŸãã
Kotlinã«ã¯Maybeã¯ã©ã¹ã¯å¿ èŠãããŸãããå€ãè¿ããã©ãããè¿ãæ©èœã¯ãåã·ã¹ãã ã«æ¢ã«åãã£ãŠããããã§ãã çµæã®ãªãã·ã§ã³æ§ã¯ããã°ã©ã ã§éåžžã«äžè¬çã§ãããããèšèªã®ã³ã¢ã§ãããç¶æããã®ãçã«ããªã£ãŠããŸãã ããã«ãããå©äŸ¿æ§ãšããã©ãŒãã³ã¹ã®äž¡æ¹ãåäžããŸãã
val s: String? = if (Math.random() < 0.5) "Yay!" else null println("length of string is .... ${ s.length() }")
è¡ã®é·ããèšç®ããããšããŠããããã2è¡ç®ã¯ããã§ã¯ã³ã³ãã€ã«ãããŸããã ããã¯ç°¡åã«ä¿®åŸ©ã§ããŸãã
val s: String? = if (Math.random() < 0.5) "Yay!" else null println("length of string is .... ${ s?.length() ?: -1 }")
ãsïŒ.LengthïŒïŒãã³ã³ã¹ãã©ã¯ãã¯ãæååããnullãã ã£ãå Žåã¯ãnullããè¿ããã?:ãæŒç®åã¯ãnullããå·ŠåŽã«ãããšãã«å³åŽãè¿ããŸãã ã€ãŸããçªç¶è¡ããŸã ãªãå Žåãã³ãŒãã¯ã-1ããåºåããŸãã
Kotlinã«ã¯ãnullãåãæäœããããã®å®å šãªããŒã«ã»ããããããŸãã®ã§ããå®å¿ãã ããã ããããç°¡æœã«ããããã«ããã«ã€ããŠã¯è©±ããªãã§ãã ããã
代ããã«ãåã«èª¬æã®ããã«ãKotlinã§å€å察å¿ãããã®ãå®çŸ©ããŸãããã
sealed class Maybe<out T> { object None : Maybe<Nothing>() data class Just<T>(val t: T) : Maybe<T>() }
ãã¡ãããæ§æã¯Haskellã»ã©çãã¯ãããŸããããããªãåãå ¥ããããŸãã ãããŒã¿ã修食åã¯ãªãã·ã§ã³ã§ãããããã€ãã®äŸ¿å©ãªæ©èœãè¿œå ãããŠããŸãã
ãã¹ãŠãé©ãããšãªãæ©èœããŸãã
val j = Maybe.Just(1) val (i) = j
ããã§ã¯ãå éšã«æ°å€ïŒIntïŒãå«ãã ããå®çŸ©ããŠãããæ°å€ãæœåºããŠæ»ããŸãã èšåãããã¿ã€ãã¯ãããŸããããããã¯ãã¹ãŠèªåçã«è¡šç€ºãããŸãã ã¡ããã©ããã€ãã®ãã£ãŒã«ãããã£ãå Žåãããããã¹ãŠãæœåºããããšãã§ããŸãããããå®éã«ãã®æ§ç¯ã®ç®çã§ãïŒ
data class Pet(val name: String, val age: Int) val alice = Pet("Alice", 6) val (name, age) = alice
ãããããã¿ãŒã³ãããã³ã°ã¯ã©ãã§ããããã ããã¯ãŸãã«ãå°å°ããããããŒã¯ãŒããå¿ èŠãšããŠãããã®ã§ãã ããã«ãããã³ã³ãã€ã©ã¯ãJustããã³None以å€ã«Maybeã®ä»ã®ãµãã¯ã©ã¹ãååšã§ããªãããšãèªèãããã¹ãŠã®ããªã¢ã³ããåå²ããå Žåãelseåå²ã¯äžèŠã§ãã
class User(val age: Int) fun lookupFromDB(s: String): Maybe<User> = Maybe.None fun printUser(username: String) { val rec = lookupFromDB(username) when (rec) { is Maybe.None -> println("not found") is Maybe.Just<User> -> println("${rec.t.age} years old") } }
åäžã®äžå€ã®ã幎霢ããã£ãŒã«ããæã€åçŽãªã¯ã©ã¹ã¯äžèšã§å®çŸ©ãããŠããŸãã lookupFromDBã¡ãœããã¯ããŒã¿ããŒã¹ãžã®ã¢ã¯ã»ã¹ãæš¡å£ãã `Maybe`ãè¿ããŸãã ç§ãã¡ã®å Žåãåžžã«Noneã§ãããããã¯åãªãäŸã§ãã
ãã®åŸãæ»ãå€ã¯ãwhenãæŒç®åã䜿çšããŠåã«ããããããŸãã `when`æ§æã䜿çšãããšãå€ãã®ããšãã§ããŸãã ç¹ã«ãåŒæ°ãåãšæ£ããäžèŽãããåŸãå³åŽã®å åŽã§ãåŒæ°ã¯ããã«å¿ããŠåãå€æŽããŸãã ãã®ããã2çªç®ã®ãã©ã³ãã®å³åŽã§ã¯ãã¯ã©ã¹ãUserãã®ãã£ãŒã«ããtããäžå¿ èŠãªåŒãªãã§äœ¿çšã§ããŸãã
äžå€æ§
Kotlinã¯çŽç²ã«æ©èœçãªèšèªã§ã¯ãªããããäžå€ãªããžã§ã¯ãã¯åçã®æ¡ä»¶ã§å¯å€ãªããžã§ã¯ããšå ±åããŸãã èšèšã§ã¯ãããã°ã©ããŒãäžå€ãªããžã§ã¯ãã䜿çšããããšãæ§ããã«å¥šå±ããŸãããäžè¬ã«ãéžæã¯éçºè ã«åžžã«ãããŸãã
ããšãã°ãããã«ïŒ
data class Person(var name: String, var age: Int) val p = Person("Mike", 31) p.name = "Bob"
ããã§ããpãã¯äžå€ã®å€ïŒå€ïŒã§ãã Javaã®ãæçµå€æ°ãããŸãã¯Haskell / FïŒã®ãletãã«äŒŒãŠããŸãã ãã ãããã®ãªããžã§ã¯ãã®å 容ã¯å¯å€å€æ°ïŒå¯å€ïŒã§æ§æãããŠãããããåå²ãåœãŠã§ããŸãã IDEã®åŒ·èª¿è¡šç€ºã¯ãå¯å€ãã£ãŒã«ããšäžå€ãã£ãŒã«ããåºå¥ããã®ã«åœ¹ç«ã¡ãŸãã
åãäŸã§ããããã¹ãŠã®ãªã³ã¯ã¯äžå€ã§ãïŒ
data class Person(val name: String, val age: Int) val mike = Person("Mike", 31) val olderMike = mike.copy(age = 32)
`data`ã¯ã©ã¹ã®ã³ããŒã¡ãœããã¯èªåçã«äœæãããŸãã ã¯ã©ã¹ã®åãã£ãŒã«ãã«ã¯ãããã©ã«ãã§çŸåšã®å€ã«çããååä»ããã©ã¡ãŒã¿ãŒããããŸãã çµæãšããŠãæ°ããã埮調æŽããªããžã§ã¯ããäœæããããã«äœ¿çšãããšäŸ¿å©ã§ãã
ãªã¹ãã¯ããã©ã«ãã§äžå€ã§ãïŒ
val people = listOf(mike, olderMike) people.add(Person("Bob", 50)) // ERROR val peopleDB = arrayListOf(mike, olderMike) peopleDB.add(Person("Bob", 50)) val view: List<Person> = peopleDB val snapshot = peopleDB.toList()
2è¡ç®ã¯ã³ã³ãã€ã«ããŸããïŒ `listOfïŒïŒ`ã¯äžå€ãªã¹ããè¿ããŸãã ãããã4è¡ç®ã§ã¯ããã¹ãŠãæŽç¶ãšããŠããŸããããã¯ãå€æŽå¯èœãªãArrayListããå ·äœçã«èŠæ±ããããã§ãã ãã¡ãããã©ã®ãªã¹ããåžžã«äžå€ã® `List`ã€ã³ã¿ãŒãã§ãŒã¹ã«æã¡èŸŒãŸãããèªã¿åãå°çšãã¥ãŒããäœæã§ããŸãã
çŸæç¹ã§ã¯ãèšèªã«ã¯ãªã¹ãã®çµã¿èŸŒã¿æ§æããªããããå¯å€æ°ã®åŒæ°ãæã€é¢æ°ã䜿çšããŠãªã¹ããäœæããŸãã
ãããã³ã°ããã£ã«ã¿ãªã³ã°ãåæžããã®ä»ã®å©ç¹
Kotlinã¯ã©ã ãåŒããµããŒãããæ©èœçãªäžçããã®äžè¬çãªã¡ãœããã§æšæºJDKã³ã¬ã¯ã·ã§ã³ãæ¡åŒµããŸãã ããã¯Java 6ãŸã§äœ¿çšã§ãããããã©ã®Androidããã€ã¹ã§ã䜿çšã§ããŸãã
val nums = listOf(1, 2, 3, 4) val r = nums.map { it * 2 }.sum() // r == 20
ãitãã¯ã©ã ããã©ã¡ãŒã¿ã®èªååã§ãããã©ã ããåŒæ°ã1ã€ã ãåãå Žåã«è¡šç€ºãããããšã«æ³šæããŠãã ããã ãã¡ãããèªåã§ãã€ã§ãããããããããååãèšå®ã§ããŸãã ãã®ãããããšãã°ããã¹ããããã©ã ãã§è¡ãããšããå§ãããŸãã
ããã§ããmapãã¯æ¡åŒµæ©èœã§ãã Kotlinã§ã¯ããã®ãããªé¢æ°ãä»»æã®ã¯ã©ã¹ã«è¿œå ããŠãå€éšAPIãæ¹åã§ããŸãã ããã¯ãéçã¡ãœããã䜿çšããjava `FooUtils`ã«äŒŒãŠããŸãããã¯ããã«äŸ¿å©ã§ãã æ¡åŒµé¢æ°ã¯æšæºã©ã€ãã©ãªã§ç©æ¥µçã«äœ¿çšãããJavaããã¯ã©ã¹ã«æ©èœãè¿œå ããKotlinèªäœã®ã€ã³ã¿ãŒãã§ã€ã¹ã®éãæžãããŸãã
ããé«åºŠãªäŸïŒ
val strs = listOf("fish", "tree", "dog", "tree", "fish", "fish") val freqs = strs.groupBy { it }.mapValues { it.value.size() } println(freqs) // {fish=3, tree=2, dog=1}
ååž°
é¢æ°åããã°ã©ãã³ã°ã®ãã©ãã€ã ã§ã¯ã埪ç°ã³ãŒãã¯ãã°ãã°ååž°çãªé¢æ°åŒã³åºããšããŠäŸ¿å©ã«è¡šçŸãããŸãã ããã©ãŒãã³ã¹ã倱ããªãããã«ãHaskellã®ãããªèšèªã³ã³ãã€ã©ã¯ãããããæ«å°ŸåŒã³åºãæé©åïŒæ«å°ŸåŒã³åºãæé©åïŒã䜿çšããŸãã ãã®æé©åã¯ãååž°åŒã³åºããé¢æ°ã®æåŸã®æäœã§ããå Žåã«ã®ã¿æ©èœããKotlinã³ã³ãã€ã©ãŒã¯ããããã§ãã¯ããŸãã
æãåçŽãªäŸïŒæ°åŠé¢æ°ã®åºå®å°æ°ç¹ã¯ãé¢æ°ã®çµæããã®åŒæ°ãšçãããªãå€ã§ãã åºå®ã³ãµã€ã³ãã€ã³ããæ€çŽ¢ããå Žåã¯ããã¹ãŠãå®å®ãããŸã§ãµã€ã¯ã«ã§ã³ãµã€ã³çµæã転éã§ããŸãã æç¶ãçãªå®è£ ïŒ
private fun cosFixpoint(): Double { var x = 1.0 while (true) { val y = Math.cos(x) if (x == y) return y x = y } }
éåžžã«ç°¡åïŒ1.0ããå§ããŠãçµæãåŒæ°ãšçãããªããŸã§ã³ãµã€ã³ãèšç®ããŸãã
åãããšã§ãããååž°ãéããŠïŒ
tailrec fun cosFixpoint(x: Double = 1.0): Double { val r = Math.cos(x) return if (x == r) x else cosFixpoint(r) }
ãŸãã¯ã1è¡ã§ãïŒ
import java.lang.Math.cos tailrec fun f(x: Double = 1.0): Double = if (x == cos(x)) x else f(cos(x)))
JITã `Math.cosïŒxïŒ`ãžã®ã³ãŒã«ããã¯ãæé©åããæ¹æ³ãèŠã€ãåºãã°ããã®ããŒãžã§ã³ã¯ä»ã®2ã€ãšåããããéãåäœããã¯ãã§ãã
ã«ã¬ãŒãéšå䜿çšãäœæ²
ãããã¯ãã¹ãŠã®é¢æ°åèšèªãæããªããã°ãªããªããã®ã§ãããæ¥åžžã®ã¿ã¹ã¯ã«éåžžã«å¿ èŠã§ãããšã¯èšããŸããã ã«ãªãŒåã¯ãå€ãã®å€æ°ã®æ©èœã1ã€ã®åŒæ°ã®è€æ°ã®æ©èœã®ãã§ãŒã³ã«åå²ããŸãã éšåé©çšã«ãããé¢æ°ã®äžéšã®ãã©ã¡ãŒã¿ãŒãä¿®æ£ããåŒæ°ã®å°ãªãé¢æ°ãååŸã§ããŸãã
Kotlinã¯ãã®ãããªãããã«äœ¿ãããåã³ãæäŸããŸããããååã«æè»ãªã®ã§ãããããã¹ãŠãfunKtionaleã©ã€ãã©ãªã«ãšã¬ã¬ã³ãã«å®è£ ã§ããŸãã
import org.funktionale.currying.* val sum2ints = { x: Int, y: Int -> x + y } val curried: (Int) -> (Int) -> Int = sum2ints.curried() assertEquals(curried(2)(4), 6) val add5 = curried(5) assertEquals(add5(7), 12)
...ãŸã...
import org.funktionale.partials.* val format = { prefix: String, x: String, postfix: String -> "${prefix}${x}${postfix}" } val prefixAndBang = format(p3 = "!") // Passing just the first parameter will return a new function val hello = prefixAndBang(p1 = "Hello, ") println(hello("world"))
é 延ããã©ãŒãã³ã¹ïŒé 延ïŒ
Kotlinã¯ãæ lazãªãèšèªã«å±ããŠããŸãããã€ãŸããèšè¿°ãããŠããå Žæã§èšç®ãè¡ãããŸãïŒãã£ãšãéãæ¹æ³ã§èµ·ãããŸãïŒïŒã ç§ã®ç¥ãéããHaskell以å€ã®å ±éèšèªã¯ããã©ã«ãã§lazy-by-defaultã䜿çšããŸããã
ãã¡ãããé 延èšç®ã¯ã©ã€ãã©ãªãä»ããŠå©çšã§ããŸãã å®éã®äŸãèããŠã¿ãŸãããããã®ã³ã°ãç¡å¹ã«ãªã£ãŠããå Žåã«ãã°è¡ãäœæããªãæ¹æ³ã¯ïŒ
val loggingEnabled = System.getProperty("log") != null fun log(s: String): Unit = if (loggingEnabled) println(s) fun log(ls: () -> String): Unit = if (loggingEnabled) println(ls())
ããã§ããã®ã³ã°é¢æ° `log`ã¯ãªãŒããŒããŒããããŸã-æååãæž¡ãããèŠæ±ã«å¿ããŠæååãèšç®ããé¢æ°ãæž¡ãããšãã§ããŸãïŒ
log("now!") log { "calculate me later" }
é¢æ°åããã°ã©ãã³ã°ã§ã¯ãç¡éã®é·ãã®ãªã¹ããäœæãããå¯èœãªéãæ laãã€äžŠåãã«ãªã¹ããæäœãããšäŸ¿å©ãªããšããããããŸãã ãã®ãããªæäœã®åçŽãã¯ãäžè¬çãªé¢æ°åããã°ã©ãã³ã°ã®éèŠãªæ©èœã®1ã€ã§ãã
ããŒãžã§ã³8以éãJavaã§ããããå¯èœã«ãªããKotlinã䜿çšããå ŽåïŒ
val ONE = BigInteger.ONE fun primes(n: Long) = Stream .iterate(ONE) { it + ONE } .filter { it.isProbablePrime(16) } .limit(n) .toList()
Javaã§ã¯ãç¡éãªã¹ãã¯ã¹ããªãŒã ãšåŒã°ããŸãã ãã¹ãŠã®æ£ã®æŽæ°ã®é 延ãªã¹ããäœæããŸãã 次ã«ãMiller-Rabinæ€å®ã«åŸã£ãŠç¢ºçïŒ1-ïŒ1/4ïŒ^ 16ïŒã§åçŽãªãã®ã®ã¿ãéžæããŸãã ãã®åŸããããã®æåã® `n`ãéåžžã®ãªã¹ãã®åœ¢åŒã§è¿ããŸãã å€å žçãªé¢æ°åããã°ã©ãã³ã°ã
ããããã©ãã ãéãåäœããŸããïŒ
repeat(3) { val t = measureTimeMillis { primes(100000) } println("Took $t msec") }
ç§ã®ã©ãããããã§ã¯ã2åç®ã®å®è¡ïŒJITããŠã©ãŒã ã¢ããïŒãããèšç®ã«1.5ç§ããããŸããã
ããããå¯äœçšã®ãªãé¢æ°ã®ãã§ãŒã³ãäœæããããšã®ãã¹ãŠã¯ã䞊ååã®å®¹æãã«ãããŸãã ãã³ãã®è ã®ç°¡åãªåããåã£ãŠ......
fun primes(n: Long) = Stream .iterate(ONE) { it + ONE } .parallel() .filter { it.isProbablePrime(16) } .limit(n) .toArray()
ç§ãã¡ãããããšã¯ãã¹ããªãŒã ã« `parallelïŒïŒ`åŒã³åºããæ¿å ¥ããããšã ãã§ããã ããã«ããã以éã®ãã¹ãŠã®æäœã¯è€æ°ã®ã¹ã¬ããã§èµ·åãããŸãã 枬å®ã§ã¯ãçç£æ§ã3åã«å¢å ããŸãããããã0.5ç§ã§ãã ç§ã«ãšã£ãŠã¯ããã»ã©æªããªãïŒ
ãœãããŠã§ã¢ãã©ã³ã¶ã¯ã·ã§ã³ã¡ã¢ãª
ãœãããŠã§ã¢ãã©ã³ã¶ã¯ã·ã§ã³ã¡ã¢ãªïŒSTMïŒã¯ã䞊åã³ãŒããèšè¿°ãã1ã€ã®æ¹æ³ã§ãã ãã®ææ³ã¯ãHaskellã®ç¥å ã®1人ã§ããSimon Peyton-Jonesã®èšäºã§è©³ãã説æãããŠããŸã ã
ããã¯ã䜿çšãã代ããã«ã次ã®ããã«èšè¿°ããŸãã
var account1 = 5 var account2 = 0 fun transfer(amount: Int) { atomic { account1 -= amount account2 += amount } }
ããã°ã©ããŒã®èŠ³ç¹ããèŠããšãã¢ãããã¯ãããã¯å ã§çºçãããã¹ãŠã¯åäžã®ãã©ã³ã¶ã¯ã·ã§ã³ã§å³åº§ã«å®è¡ãããå éšã«ç«¶åç¶æ ã¯ãããŸããã ãã ããåæã«ããã®ãããã¯ã«è€æ°ã®ã¹ã¬ãããåæã«ååšããããšã劚ãããã®ã¯ãããŸããã ãšãŠããšã¬ã¬ã³ãã
åçŽãªå®è£ ã§ã¯1ã€ã®ã°ããŒãã«ããã¯ã䜿çšã§ããŸãããéåžžã«é ããªããŸãã ãããã£ãŠãå®éã«ã¯ãã·ã¹ãã ã¯1ã€ã®ã¹ããªãŒã ã®ãã¹ãŠã®ããŒã¿å€æŽãèšé²ãã競åç¶æ³ããã£ããããŸãã 競åãçºçããå ŽåããŠãããã¯åèµ·åããŸãã ããã¯Haskellã§ããŸãå®è£ ãããŠããŸãã
ããã§ããKotlinã¯STMãçŽæ¥ãµããŒãããŠããŸããã ããããããã¯æ±ºããŠåé¡ã§ã¯ãããŸãããJVMãä»ããŠScala STMãªã©ã®ã©ã€ãã©ãªãããã«ã¯ããäœã¬ãã«ã®ãã©ã³ã¶ã¯ã·ã§ã³ã¡ã¢ãªïŒããŒããŠã§ã¢ãã©ã³ã¶ã¯ã·ã§ã³ã¡ã¢ãªïŒãèªç±ã«äœ¿çšã§ããããã§ãã ãã
Intelã®ææ°ïŒéåžžã«ææ°ã®ïŒãããã¯ãTSXãšåŒã°ããäžé£ã®æ¡åŒµæ©èœããµããŒãããŠããŸãã TSXã䜿çšãããšãéã¬ãã«ã§ã¢ãããã¯ãã©ã³ã¶ã¯ã·ã§ã³ãäœæã§ããŸãã RAMã®å€æŽã¯ãã£ãã·ã¥ã«æžã蟌ãŸããã¹ã¬ããéã®ç«¶åã¯CPUèªäœã«ãã£ãŠè¿œè·¡ãããŸãã 競åãçºçããå ŽåãCPUã¯ãããã°ã©ã ãåè©Šè¡ããããéåžžã®ããã¯ã䜿çšããããšãæåŸ ããŠãã©ã³ã¶ã¯ã·ã§ã³ããã£ã³ã»ã«ããŸãã ãã¹ãŠãèšç»ã©ããã«é²ãã å Žåããã£ãã·ã¥ã¯äžåºŠã«RAMãšåæãããŸãã
Java 8ãUpdate 40ã以éãäºææ§ã®ããããã»ããµã§ã¯ããããããRTMããã¯ããããã©ã«ãã§æå¹ã«ãªã£ãŠããŸã[1] ã ããã«ãããJavaã®ãã¹ãŠã®åæãããã¯ãTSXã䜿çšããŠäœã¬ãã«ã®ãã©ã³ã¶ã¯ã·ã§ã³ã«éæ³ã®ããã«å€æãããŸãã ããã¯ã€ãŸããã³ãŒããå®éã«äžŠè¡ããŠå®è¡ãããããã«ãªã£ãããšãæå³ããŸãã JVMã¯ããã«ã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠãé »ç¹ã«åèµ·åãããããã¯ãèŠã€ããããããæšæºããã¯ã«å€æããŸãã Kotlinã¯JVMã§å®è¡ãããããããã¹ãŠèªåçã«åäœããŸãã
ããã«ããããã¹ãŠã®éèŠãªã³ãŒãã1ã€ã®å€§ããªåæãããã¯ã«èšè¿°ã§ããé床ã«å€§ããªåé¡ãæããããšã¯ãããŸããã ãã¡ãããææ°ã®ããŒããŠã§ã¢ããæã¡ã®å Žåã
ãã ããå¶éããããŸã-STMã¯ããããã¯ã®åæ¢/åèµ·å/ãã£ã³ã»ã«ãªã©ã®è¿œå ã®ãœãããŠã§ã¢æ©èœãæäŸããŸãã TSXã¯ãããè¡ãããšãã§ããŸãããããããJVMã¯çŸæç¹ã§ã¯ãµããŒãããŠããŸããã ãããã£ãŠãããã«å¶åŸ¡ãå¿ èŠãªå Žåã¯ããã©ã³ã¶ã¯ã·ã§ã³å€æ°ãã±ãŒã¹ã«æ¥ç¶ããå¿ èŠããããŸãã
import scala.concurrent.stm.japi.STM.* val counter = newRef(10) try { atomic { increment(counter, 1) println("counter is ${counter.get()}") // -> 11 throw Exception("roll back!!") } } catch(e: Exception) { println("counter is ${counter.get()}") // -> 10 }
Haskellã«ã¯å¥ã®ãšã¬ã¬ã³ããªããªãã¯ããããŸã-ãã®åã·ã¹ãã ã¯ããã©ã³ã¶ã¯ã·ã§ã³å€æ°ãåæãããã¯å ã§æä»çã«å©çšå¯èœã§ããããšãä¿èšŒããŸããããã«ããã奜ããªæ¹æ³ã§ãã«ãã¹ã¬ãããå¿ããããšãã§ããŸããã Kotlinã§ãåæ§ã®ããšãã§ããŸãã
class ThreadBox<T>(v: T) { private val value = v @Synchronized fun locked<R>(f: T.() -> R): R = value.f() } val bank = ThreadBox(object { val accounts = intArrayOf(10, 0, 0, 0) }) fun transfer(from: Int, to: Int, amount: Int) { bank.locked { accounts[from] -= amount accounts[to] += amount } }
ãThreadBoxãã¯ãä»»æã®ãå€ããªããžã§ã¯ããžã®ããã©ã€ããŒãããã€ã³ã¿ãŒãä¿åããã¯ã©ã¹ã§ãã ãããã£ãŠããã®ãªããžã§ã¯ããžã®å€éšãªã³ã¯ããªãå ŽåãTreadBoxãä»ããŠã®ã¿äœ¿çšã§ããŸãã ãã³ã¯ãªããžã§ã¯ãã宣èšãããšããobject-expresionã䜿çšããŠååã®ãªããªããžã§ã¯ããäœæããThreadBoxã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŸããããã«ããããªããžã§ã¯ããžã®å€éšåç §ããªãããšãä¿èšŒãããŸãã ãããŠãThreadBoxã¯ã@ Synchronizedã¢ãããŒã·ã§ã³ã§ä¿è·ããããããã¯ãã¡ãœããå ã®ãã€ã³ã¿ãŒã®ã¿ãæäŸããŸãã
Kotlinæ§æã¯ãåæãããã¯ã®å€éšã§ãã¢ã«ãŠã³ããé åã䜿çšããæ¹æ³ãæäŸããŸãã...ãããžã®ãªã³ã¯ãå€éšã«åºãŠããªãå Žåã®ã¿ã ãã®ãããããã¯Haskellã»ã©æ·±å»ãªé²åŸ¡çã§ã¯ãããŸããããå¿ èŠãªã³ãŒãã¯3è¡ã ãã§ãã
Github 㧠ãåãã¢ã€ãã¢ã®ããæŽç·ŽãããããŒãžã§ã³ãæçš¿ãã ããå€ãã®ãšã©ãŒãé²ããŸããã
ã³ããªã³ã«ãªããã®
èšèªéçºïŒM14ïŒã®æç¹ã§ã¯ãå¯äœçšãå¶åŸ¡ããæ¹æ³ã¯ãããŸãããããã¯ãäžéšã®ã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ãäœæãããšãã«éèŠã«ãªãå ŽåããããŸãã
ãŸããé«æ§èœã§äžå€ã®ããŒã¿æ§é çšã®ããã€ãã£ããã©ã€ãã©ãªã¯ãããŸããã ããã¯ããã®ãããªæ§é ãèšèªèªäœã«åã蟌ãŸããŠããClojureãšScalaãšã¯å¯Ÿç §çã§ãã æãèå³æ·±ãã®ã¯ãæè¿å ¬éãããCHAMPã¢ã«ãŽãªãºã ã䜿çšããã°ãKotlinã®ïŒScala / Clojureãšæ¯èŒããŠïŒã¯ããã«çç£çãªå®è£ ãäœæã§ããããšã§ãã
UPD 1
grosswsãææããããã«ã å
ã®èšäºã®ãã¬ãŒãº
Oracle Webãµã€ãã®å ¬åŒããã¥ã¡ã³ããšäžèŽããŠããŸããã
äœãæ£ããã®ããäœãééã£ãŠããã®ããå€æããããšã¯æ³å®ããŠããŸããããããçšåºŠã®ç念ãæã£ãŠãã®ç¬éããšã£ãŠãã ããã
docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
oracle.com/technetwork/java/javase/8u40-relnotes-2389089.html
Java 8 Update 40以éã§ã¯ãCPUããµããŒãããå ŽåããããããRTMããã¯ããããã©ã«ãã§æå¹ã«ãªããŸãã
Oracle Webãµã€ãã®å ¬åŒããã¥ã¡ã³ããšäžèŽããŠããŸããã
-XXïŒ+ UseRTMLockingã¯ããã©ãŒã«ããã¯ãã³ãã©ãŒãšããŠéåžžã®ããã¯ã¡ã«ããºã ã䜿çšããŠããã¹ãŠã®èšåŒµããããã¯ã«å¯ŸããŠå¶éä»ããã©ã³ã¶ã¯ã·ã§ã³ã¡ã¢ãªïŒRTMïŒããã¯ã³ãŒããçæããŸãã ãã®ãªãã·ã§ã³ã¯ããã©ã«ãã§ç¡å¹ã«ãªã£ãŠããŸãã
äœãæ£ããã®ããäœãééã£ãŠããã®ããå€æããããšã¯æ³å®ããŠããŸããããããçšåºŠã®ç念ãæã£ãŠãã®ç¬éããšã£ãŠãã ããã
docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
oracle.com/technetwork/java/javase/8u40-relnotes-2389089.html