์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ฅผ ์œ„ํ•œ ์Šค์นผ๋ผ ํŠœํ† ๋ฆฌ์–ผ

Language

Michel Schinz, Philipp Haller ์ง€์Œ. ์ดํฌ์ข… ([email protected]) ์˜ฎ๊น€.

์‹œ์ž‘ํ•˜๋ฉด์„œ

์ด ๋ฌธ์„œ๋Š” Scala ์–ธ์–ด์™€ ๊ทธ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์†Œ๊ฐœํ•œ๋‹ค. ์–ด๋А ์ •๋„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฒฝํ—˜์ด ์žˆ์œผ๋ฉฐ Scala๋ฅผ ํ†ตํ•ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฐฐ์šฐ๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด ์กŒ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋…์ž๊ฐ€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ, ํŠนํžˆ Java์— ๋Œ€ํ•œ ์ง€์‹์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

์ฒซ ๋ฒˆ์งธ ์˜ˆ์ œ

์ฒซ๋ฒˆ์งธ ์˜ˆ์ œ๋กœ ํ”ํžˆ ์“ฐ์ด๋Š” Hello world ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์ž. ์ด ํ”„๋กœ๊ทธ๋žจ์€ ๊ทธ๋‹ค์ง€ ๋ฉ‹์ง€์ง€๋Š” ์•Š์ง€๋งŒ ์–ธ์–ด์— ๋Œ€ํ•œ ๋งŽ์€ ์ง€์‹ ์—†์ด๋„ Scala ์–ธ์–ด๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ ํ•„์š”ํ•œ ๋„๊ตฌ๋“ค์˜ ์‚ฌ์šฉ๋ฒ•์„ ์‰ฝ๊ฒŒ ๋ณด์—ฌ ์ค„ ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜๋ฅผ ๋ณด์ž:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, world!")
  }
}

์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์€ ์ด ํ”„๋กœ๊ทธ๋žจ์˜ ๊ตฌ์กฐ๊ฐ€ ์ต์ˆ™ ํ•  ๊ฒƒ์ด๋‹ค. ํ”„๋กœ๊ทธ๋žจ์€ ๋ฌธ์ž์—ด ๋ฐฐ์—ด ํƒ€์ž…์˜ ๋ช…๋ น์ค„ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ์ด๋ฆ„์ด main์ธ ํ•จ์ˆ˜ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด ํ•จ์ˆ˜์˜ ๊ตฌํ˜„์€ ํ•˜๋‚˜์˜ ๋˜ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š”๋ฐ ๋ฏธ๋ฆฌ ์ •์˜ ๋œ ํ•จ์ˆ˜ println์— ์–ด๋””์„ ๊ฐ€ ๋งŽ์ด ๋ณธ ๋ฐ”๋กœ ๊ทธ ํ™˜์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด ํ˜ธ์ถœ ํ•œ๋‹ค. main ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ๋Œ๋ ค์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌํ„ด ํƒ€์ž…์„ ์„ ์–ธ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์—๊ฒŒ ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์€ main ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” object ์„ ์–ธ์ผ ๊ฒƒ์ด๋‹ค. ์ด ์„ ์–ธ์€ ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ์ด๋Š” ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ์„ ๊ฐ€์ง€๋Š” ํด๋ž˜์Šค๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์˜ ์„ ์–ธ์€ HelloWorld๋ผ๋Š” ํด๋ž˜์Šค์™€ ์—ญ์‹œ HelloWorld๋ผ๊ณ  ์ด๋ฆ„ ๋ถ™์ธ ์ด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•จ๊ป˜ ์ •์˜ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์ธ์Šคํ„ด์Šค๋Š” ์ฒ˜์Œ ์‚ฌ์šฉ ๋  ๋•Œ์— ํ•„์š”์— ๋”ฐ๋ผ ๋งŒ๋“ค์–ด ์ง„๋‹ค.

๋˜‘๋˜‘ํ•œ ๋…์ž๋“ค์€ ์ด๋ฏธ ๋ˆˆ์น˜์ฑ˜๊ฒ ์ง€๋งŒ ์œ„์˜ ์˜ˆ์ œ์—์„œ main ํ•จ์ˆ˜๋Š” static์ด ์•„๋‹ˆ๋‹ค. Scala์—๋Š” ์ •์  ๋ฉค๋ฒ„(ํ•จ์ˆ˜๋“  ํ•„๋“œ๋“ )๋ผ๋Š” ๊ฐœ๋…์ด ์•„์˜ˆ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ํด๋ž˜์Šค์˜ ์ผ๋ถ€๋กœ ์ •์  ๋ฉค๋ฒ„๋ฅผ ์ •์˜ํ•˜๋Š” ๋Œ€์‹ ์— Scala ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์€ ์ •์ ์ด๊ธฐ ์›ํ•˜๋Š” ๋ฉค๋ฒ„๋“ค์„ ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด์•ˆ์— ์„ ์–ธํ•œ๋‹ค.

์˜ˆ์ œ๋ฅผ ์ปดํŒŒ์ผ ํ•˜๊ธฐ

์˜ˆ์ œ๋ฅผ ์ปดํŒŒ์ผ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ Scala ์ปดํŒŒ์ผ๋Ÿฌ์ธ scalac๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. scalac๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋“ค๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ์†Œ์ŠคํŒŒ์ผ๊ณผ ํ•„์š”์— ๋”ฐ๋ผ ๋ช‡๊ฐœ์˜ ์˜ต์…˜๋“ค์„ ์ธ์ž๋กœ ๋ฐ›์•„ ํ•œ๊ฐœ ๋˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ์˜ค๋ธŒ์ ํŠธ ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค. scalac๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ ํŒŒ์ผ์€ ํ‘œ์ค€์ ์ธ Java ํด๋ž˜์Šค ํŒŒ์ผ์ด๋‹ค.

์œ„์˜ ์˜ˆ์ œ ํ”„๋กœ๊ทธ๋žจ์„ HelloWorld.scala๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ €์žฅํ–ˆ๋‹ค๋ฉด, ์•„๋ž˜์˜ ๋ช…๋ น์œผ๋กœ ์ปดํŒŒ์ผ ํ•  ์ˆ˜ ์žˆ๋‹ค (๋ถ€๋“ฑํ˜ธ >๋Š” ์‰˜ ํ”„๋กฌํ”„ํŠธ์ด๋ฏ€๋กœ ํ•จ๊ป˜ ์ž…๋ ฅํ•˜์ง€ ๋ง๊ฒƒ) :

> scalac HelloWorld.scala

์ด์ œ ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์— ๋ช‡๊ฐœ์˜ ํด๋ž˜์Šค ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ์ค‘์— ํ•˜๋‚˜๋Š” HelloWorld.class์ด๋ฉฐ scala ๋ช…๋ น์„ ํ†ตํ•ด ๋ฐ”๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ๋‹ค์Œ ์žฅ์„ ๋ณด์ž.

์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ

์ผ๋‹จ ์ปดํŒŒ์ผ ๋˜๋ฉด Scala ํ”„๋กœ๊ทธ๋žจ์€ scala ๋ช…๋ น์„ ํ†ตํ•ด ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ Java ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” java ๋ช…๋ น๊ณผ ๋งค์šฐ ๋น„์Šทํ•˜๋ฉฐ ๋™์ผํ•œ ์˜ต์…˜์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ์œ„์˜ ์˜ˆ์ œ๋Š” ์•„๋ž˜์˜ ๋ช…๋ น์œผ๋กœ ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์˜ˆ์ƒํ•œ๋Œ€๋กœ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

> scala -classpath . HelloWorld

Hello, world!

์ž๋ฐ”์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ

Scala์˜ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” Java ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ Java ํด๋ž˜์Šค๋ฅผ ๊ฐ„๋‹จํžˆ ์ž„ํฌํŠธ ํ•˜๋ฉด ๋˜๋ฉฐ, java.lang ํŒจํ‚ค์ง€์˜ ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ์ž„ํฌํŠธ ํ•˜์ง€ ์•Š์•„๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์•„๋ž˜๋Š” Scala๊ฐ€ Java์™€ ์–ผ๋งˆ๋‚˜ ์ž˜ ์–ด์šธ๋ฆฌ๋Š”์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ์ด๋‹ค. ์šฐ๋ฆฌ๋Š” ์•„๋ž˜ ์˜ˆ์ œ์—์„œ ํ˜„์žฌ์˜ ๋‚ ์งœ๋ฅผ ๊ตฌํ•˜์—ฌ ํŠน์ • ๊ตญ๊ฐ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ ํ•  ๊ฒƒ์ด๋‹ค. ์ด๋ฅผํ…Œ๋ฉด ํ”„๋ž‘์Šค(๋ถˆ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์Šค์œ„์Šค์˜ ์ผ๋ถ€ ์ง€์—ญ๋„ ๋™์ผํ•œ ํ˜•์‹์„ ์‚ฌ์šฉํ•œ๋‹ค)๋ผ ํ•˜์ž.

Java์˜ ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Date์™€ DateFormat๊ณผ ๊ฐ™์€ ๊ฐ•๋ ฅํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. Scala๋Š” Java์™€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์„œ๋กœ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋™์ผํ•œ ์—ญํ• ์„ ํ•˜๋Š” Scala ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ Java ํŒจํ‚ค์ง€๋ฅผ ๊ฐ„๋‹จํžˆ ์ž„ํฌํŠธํ•˜์—ฌ ์ด์šฉํ•˜์ž.

import java.util.{Date, Locale}
import java.text.DateFormat._

object FrenchDate {
  def main(args: Array[String]): Unit = {
    val now = new Date
    val df = getDateInstance(LONG, Locale.FRANCE)
    println(df format now)
  }
}

Scala์˜ ์ž„ํฌํŠธ ๊ตฌ๋ฌธ์€ Java์˜ ๊ทธ๊ฒƒ๊ณผ ๋งค์šฐ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ ์‚ฌ์‹ค ์ข€ ๋” ๊ฐ•๋ ฅํ•˜๋‹ค. ์œ„ ์˜ˆ์ œ์˜ ์ฒซ๋ฒˆ์งธ ์ค„๊ณผ ๊ฐ™์ด ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ™์€ ํŒจํ‚ค์ง€์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ์„ ํƒ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. Scala ์ž„ํฌํŠธ ๊ตฌ๋ฌธ์˜ ๋˜ ํ•œ๊ฐ€์ง€ ํŠน์ง•์€ ํŒจํ‚ค์ง€๋‚˜ ํด๋ž˜์Šค์— ์†ํ•œ ๋ชจ๋“  ์ด๋ฆ„๋“ค์„ ๋ถˆ๋Ÿฌ ์˜ฌ ๊ฒฝ์šฐ ๋ณ„ํ‘œ(*) ๋Œ€์‹  ๋ฐ‘์ค„(_) ์„ ์‚ฌ์šฉ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋ณ„ํ‘œ๋Š” Scala์—์„œ ํ•ฉ๋ฒ•์ ์ธ ์‹๋ณ„์ž(ํ•จ์ˆ˜๋ช… ๋“ฑ์— ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ)๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๋‚˜์ค‘์— ์ž์„ธํžˆ ์‚ดํŽด ๋ณผ ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ๋‘๋ฒˆ์งธ ์ค„์˜ ์ž„ํฌํŠธ ๊ตฌ๋ฌธ์€ DateFormat ํด๋ž˜์Šค์˜ ๋ชจ๋“  ๋ฉค๋ฒ„๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์ •์  ํ•จ์ˆ˜ getDateInstance์™€ ์ •์  ํ•„๋“œ LONG์ด ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.

main ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ฒ˜์Œ ํ•˜๋Š” ์ผ์€ Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์†ํ•œ Date ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ์ธ์Šคํ„ด์Šค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ˜„์žฌ์˜ ๋‚ ์งœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์ด์ „์— ๋ถˆ๋Ÿฌ์˜จ ์ •์  ํ•จ์ˆ˜ getDateInstance๋ฅผ ํ†ตํ•ด ๋‚ ์งœ ํ˜•์‹์„ ๊ฒฐ์ •ํ•˜๊ณ , ํ”„๋ž‘์Šค์— ๋งž์ถฐ์ง„ DateFormat ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ์˜ ๋‚ ์งœ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์ด ๋งˆ์ง€๋ง‰ ์ค„์€ Scala ๋ฌธ๋ฒ•์˜ ์žฌ๋ฏธ์žˆ๋Š” ํŠน์„ฑ์„ ๋ณด์—ฌ์ค€๋‹ค. ์˜ค์ง ํ•˜๋‚˜์˜ ์ธ์ž๋ฅผ ๊ฐ–๋Š” ํ•จ์ˆ˜๋Š” ๋งˆ์น˜ ์ดํ•ญ์—ฐ์‚ฐ์ž ๊ฐ™์€ ๋ฌธ๋ฒ•์œผ๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด ์ด์•ผ๊ธฐ๋Š” ๊ณง ์•„๋ž˜์˜ ํ‘œํ˜„์‹์ด:

df format now

์•„๋ž˜ ํ‘œํ˜„์‹๊ณผ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„ ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ์ € ์ข€ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ ๋˜์—ˆ์„ ๋ฟ์ด๋‹ค.

df.format(now)

์ด๋Ÿฌํ•œ ํŠน์„ฑ์€ ๊ทธ์ € ๋ณ„๊ฒƒ ์•„๋‹Œ ๋ฌธ๋ฒ•์˜ ์ผ๋ถ€ ์ธ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์ค‘์š”ํ•˜๊ฒŒ ์‚ฌ์šฉ ๋œ๋‹ค. ๊ทธ์ค‘์— ํ•˜๋‚˜๊ฐ€ ๋‹ค์Œ ์žฅ์— ๋‚˜์™€์žˆ๋‹ค.

์ด๋ฒˆ ์žฅ์—์„œ๋Š” Java์™€ Scala๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์„œ๋กœ ๋…น์•„๋“œ๋Š”์ง€์— ๋Œ€ํ•ด ๋ฐฐ์› ๋‹ค. ์ด๋ฒˆ ์žฅ์—๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜์ง€๋งŒ, Scala ์•ˆ์—์„œ Java์˜ ํด๋ž˜์Šค๋“ค์„ ์ƒ์†๋ฐ›๊ณ  Java์˜ ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ๋ฐ”๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ชจ๋“  ๊ฒƒ์€ ๊ฐ์ฒด๋‹ค

Scala๋Š” ์ˆœ์ˆ˜ํ•œ ๊ฐ์ฒด์ง€ํ–ฅ์  ์–ธ์–ด์ด๋‹ค. ์ด ๋ง์€ ๊ณง ์ˆซ์ž์™€ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“ ๊ฒƒ์ด ๊ฐ์ฒด๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉด์—์„œ Scala๋Š” Java์™€ ๋‹ค๋ฅด๋‹ค. Java์—์„œ๋Š” ๊ธฐ๋ณธ์ ์ธ ํƒ€์ž…(boolean์ด๋‚˜ int ๋”ฐ์œ„)๊ณผ ์ฐธ์กฐ ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ•จ์ˆ˜๋ฅผ ๊ฐ’๊ณผ ๋™์ผํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜๋„ ์—†๋‹ค.

์ˆซ์ž๋„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋‹ค

์ˆซ์ž๋Š” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋“ค์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ์‚ฌ์‹ค ์•„๋ž˜์™€ ๊ฐ™์€ ํ‘œํ˜„์‹์€:

1 + 2 * 3 / x

์˜ค์ง ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ๋งŒ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ด์ „ ์žฅ์—์„œ ๋ณด์•˜๋“ฏ์ด, ์œ„์˜ ํ‘œํ˜„์‹์€ ์•„๋ž˜์˜ ํ‘œํ˜„์‹๊ณผ ๋™์ผํ•˜๋‹ค.

1.+(2.*(3)./(x))

์œ„์˜ ํ‘œํ˜„์‹์ฒ˜๋Ÿผ +, * ๋“ฑ์€ Scala์—์„œ ํ•ฉ๋ฒ•์ ์ธ ์‹๋ณ„์ž์ด๋‹ค.

ํ•จ์ˆ˜๋งˆ์ € ๊ฐ์ฒด๋‹ค

Java ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์—๊ฒŒ๋Š” ๋†€๋ผ์šด ์ผ์ด๊ฒ ์ง€๋งŒ Scala์—์„œ๋Š” ํ•จ์ˆ˜๋„ ์—ญ์‹œ ๊ฐ์ฒด์ด๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜, ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜๊ฐ€ ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด์ฒ˜๋Ÿผ ํ•จ์ˆ˜๋ฅผ ๊ฐ’๊ณผ ๋™์ผํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ๋งค์šฐ ํฅ๋ฏธ๋กœ์šด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์ธ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

ํ•จ์ˆ˜๋ฅผ ๊ฐ’๊ณผ ๊ฐ™์ด ๋‹ค๋ฃจ๋Š” ๊ฒƒ์ด ์œ ์šฉํ•จ์„ ๋ณด์ด๊ธฐ ์œ„ํ•ด ์•„์ฃผ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋ฅผ ๋“ ๋‹ค. ์–ด๋– ํ•œ ํ–‰๋™์„ ๋งค์ดˆ ์ˆ˜ํ–‰ํ•˜๋Š” ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ์ƒ๊ฐํ•ด ๋ณด์ž. ์ˆ˜ํ–‰ ํ•  ํ–‰๋™์„ ์–ด๋–ป๊ฒŒ ๋„˜๊ฒจ ์ฃผ์–ด์•ผ ํ• ๊นŒ? ๋…ผ๋ฆฌ์ ์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค๋ฉด ํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ƒํ™ฉ์€ ๋งŽ์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์—๊ฒŒ ์ต์ˆ™ ํ•  ๊ฒƒ์ด๋‹ค. ๋ฐ”๋กœ ์œ ์ € ์ธํ„ฐํŽ˜์ด์Šค ์ฝ”๋“œ์—์„œ ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€์„ ๋•Œ ๋ถˆ๋ฆด ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ ๋ง์ด๋‹ค.

์•„๋ž˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํƒ€์ด๋จธ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ oncePerSecond์ด๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค. ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜์˜ ํƒ€์ž…์€ () => Unit ์ธ๋ฐ, ์ด ํƒ€์ž…์€ ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ณ  ์•„๋ฌด ๊ฒƒ๋„ ๋Œ๋ ค์ฃผ์ง€ ์•Š๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋œปํ•œ๋‹ค (Unit ํƒ€์ž…์€ C/C++์—์„œ void์™€ ๋น„์Šทํ•˜๋‹ค). ์ด ํ”„๋กœ๊ทธ๋žจ์˜ ๋ฉ”์ธ ํ•จ์ˆ˜๋Š” ์ด ํƒ€์ด๋จธ ํ•จ์ˆ˜๋ฅผ ํ™”๋ฉด์— ๋ฌธ์žฅ์„ ์ถœ๋ ฅํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ํ˜ธ์ถœํ•œ๋‹ค. ๊ฒฐ๊ตญ ์ด ํ”„๋กœ๊ทธ๋žจ์ด ํ•˜๋Š” ์ผ์€ ์ผ์ดˆ์— ํ•œ๋ฒˆ์”ฉ โ€œtime flies like an arrowโ€๋ฅผ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด ๋œ๋‹ค.

object Timer {
  def oncePerSecond(callback: () => Unit): Unit = {
    while (true) { callback(); Thread sleep 1000 }
  }
  def timeFlies(): Unit = {
    println("time flies like an arrow...")
  }
  def main(args: Array[String]): Unit = {
    oncePerSecond(timeFlies)
  }
}

์šฐ๋ฆฌ๋Š” ๋ฌธ์ž์—ด์„ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•˜์—ฌ Scala์— ์ •์˜๋œ println์„ ์‚ฌ์šฉ ํ•˜์˜€๋‹ค. ์ด ํ•จ์ˆ˜๋Š” Java์—์„œ ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” System.out์— ์ •์˜๋œ ๊ฒƒ๊ณผ ๋‹ค๋ฅด๋‹ค.

์ด๋ฆ„์—†๋Š” ํ•จ์ˆ˜

์ด ํ”„๋กœ๊ทธ๋žจ์€ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ ์กฐ๊ธˆ ๋” ๋‹ค๋“ฌ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ํ•จ์ˆ˜ timeFlies๋Š” ์˜ค์ง ํ•จ์ˆ˜ oncePerSecond์— ์ธ์ž๋กœ ๋„˜๊ฒจ์ง€๊ธฐ ์œ„ํ•ด ์ •์˜ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์— ์ฃผ๋ชฉํ•˜์ž. ์ด๋Ÿฌํ•œ ํ•œ๋ฒˆ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์— ์ด๋ฆ„์„ ๋ถ™์—ฌ ์ค€๋‹ค๋Š” ๊ฒƒ์€ ํ•„์š” ์—†๋Š” ์ผ์ผ ์ˆ˜ ์žˆ๋‹ค. ๋” ํ–‰๋ณตํ•œ ๋ฐฉ๋ฒ•์€ oncePerSecond์— ํ•จ์ˆ˜๊ฐ€ ์ „๋‹ฌ ๋˜๋Š” ๊ทธ ์ˆœ๊ฐ„ ์ด ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Scala์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฌด๋ช…ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋ฌด๋ช…ํ•จ์ˆ˜๋ž€ ๋ง ๊ทธ๋Œ€๋กœ ์ด๋ฆ„์ด ์—†๋Š” ํ•จ์ˆ˜์ด๋‹ค. ํ•จ์ˆ˜ timeFlies ๋Œ€์‹ ์— ๋ฌด๋ช…ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ์ƒˆ๋กœ์šด ๋ฒ„์ „์˜ ํƒ€์ด๋จธ ํ”„๋กœ๊ทธ๋žจ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค:

object TimerAnonymous {
  def oncePerSecond(callback: () => Unit): Unit = {
    while (true) { callback(); Thread sleep 1000 }
  }
  def main(args: Array[String]): Unit = {
    oncePerSecond(() =>
      println("time flies like an arrow..."))
  }
}

main ํ•จ์ˆ˜ ์•ˆ์— ์˜ค๋ฅธ์ชฝ ํ™”์‚ดํ‘œ =>๊ฐ€ ์žˆ๋Š” ๊ณณ์ด ๋ฌด๋ช…ํ•จ์ˆ˜์ด๋‹ค. ์˜ค๋ฅธ์ชฝ ํ™”์‚ดํ‘œ๋Š” ํ•จ์ˆ˜์˜ ์ธ์ž์™€ ํ•จ์ˆ˜์˜ ๋‚ด์šฉ์„ ๋ถ„๋ฆฌ ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์œ„ ์˜ˆ์ œ์—์„œ ์ธ์ž์˜ ๋ฆฌ์ŠคํŠธ๋Š” ๋น„์–ด์žˆ๋‹ค. ํ™”์‚ดํ‘œ์˜ ์™ผ์ชฝ์„ ๋ณด๋ฉด ๋นˆ ๊ด„ํ˜ธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํ•จ์ˆ˜์˜ ๋‚ด์šฉ์€ timeFlies์™€ ์ผ์น˜ํ•œ๋‹ค.

ํด๋ž˜์Šค์— ๋Œ€ํ•˜์—ฌ

์ง€๊ธˆ๊นŒ์ง€ ๋ณด์•˜๋“ฏ Scala๋Š” ๊ฐ์ฒด์ง€ํ–ฅ์  ์–ธ์–ด์ด๋ฉฐ ํด๋ž˜์Šค์˜ ๊ฐœ๋…์ด ์กด์žฌํ•œ๋‹ค. (์–ด๋–ค ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด๋Š” ํด๋ž˜์Šค์˜ ๊ฐœ๋…์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋‹น์—ฐํ•˜๊ฒŒ๋„ Scala๋Š” ์ด๋“ค์— ์†ํ•˜์ง€ ์•Š๋Š”๋‹ค.) Scala์˜ ํด๋ž˜์Šค ์ •์˜๋Š” Java์˜ ํด๋ž˜์Šค ์ •์˜์™€ ์œ ์‚ฌํ•˜๋‹ค. ํ•œ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด์ ์€ Scala ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ ์•„๋ž˜ ๋ณต์†Œ์ˆ˜ ์˜ˆ์ œ์— ์ž˜ ๋‚˜ํƒ€๋‚˜ ์žˆ๋‹ค:

class Complex(real: Double, imaginary: Double) {
  def re() = real
  def im() = imaginary
}

์ด ๋ณต์†Œ์ˆ˜ ํด๋ž˜์Šค๋Š” ๋‘๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š”๋‹ค. ํ•˜๋‚˜๋Š” ๋ณต์†Œ์ˆ˜์˜ ์‹ค์ˆ˜ ๋ถ€๋ถ„์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ณต์†Œ์ˆ˜์˜ ํ—ˆ์ˆ˜ ๋ถ€๋ถ„์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์ด ๋œ๋‹ค. ์ด ์ธ์ž๋“ค์€ Complex ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ ์ด์ฒ˜๋Ÿผ ๋ฐ˜๋“œ์‹œ ์ „๋‹ฌ ๋˜์–ด์•ผ ํ•œ๋‹ค: new Complex(1.5, 2.3). ํด๋ž˜์Šค๋Š” re์™€ im๋ผ๋Š” ๋‘ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ๊ฐ๊ฐ์˜ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ณต์†Œ์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ•ด๋‹น ๋ถ€๋ถ„์˜ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

์ด ๋‘ ํ•จ์ˆ˜์˜ ๋ฆฌํ„ดํƒ€์ž…์€ ๋ช…์‹œ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚˜ ์žˆ์ง€ ์•Š๋‹ค๋Š” ์‚ฌ์‹ค์— ์ฃผ๋ชฉํ•˜์ž. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด ํ•จ์ˆ˜๋“ค์˜ ์˜ค๋ฅธํŽธ์„ ๋ณด๊ณ  ๋‘˜ ๋‹ค Double ํƒ€์ž…์„ ๋ฆฌํ„ด ํ•œ๋‹ค๊ณ  ์ž๋™์œผ๋กœ ์œ ์ถ”ํ•ด ๋‚ธ๋‹ค.

ํ•˜์ง€๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์–ธ์ œ๋‚˜ ์ด๋ ‡๊ฒŒ ํƒ€์ž…์„ ์œ ์ถ”ํ•ด ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ์–ด๋–ค ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ํƒ€์ž… ์œ ์ถ”๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ  ์–ด๋–ค ๊ฒฝ์šฐ ๋ถˆ๊ฐ€๋Šฅ ํ•œ์ง€์— ๊ด€ํ•œ ๋ช…ํ™•ํ•œ ๊ทœ์น™๋„ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์€ ๋ณ„ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ์ฃผ์–ด์ง€์ง€ ์•Š์€ ํƒ€์ž…์ •๋ณด๋ฅผ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ์œ ์ถ” ํ•ด ๋‚ผ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์ปดํŒŒ์ผ ์‹œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ดˆ๋ณด Scala ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์„ ์œ„ํ•œ ํ•œ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€, ์ฃผ๋ณ€์„ ๋ณด๊ณ  ์‰ฝ๊ฒŒ ํƒ€์ž…์„ ์œ ์ถ” ํ•ด ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ์ผ๋‹จ ํƒ€์ž… ์„ ์–ธ์„ ์ƒ๋žตํ•˜๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฐ›์•„ ๋“ค์ด๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ๋ช‡๋ฒˆ์„ ๋ฐ˜๋ณตํ•˜๊ณ  ๋‚˜๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์–ธ์ œ ํƒ€์ž…์„ ์ƒ๋žตํ•ด๋„ ๋˜๊ณ  ์–ธ์ œ ๋ช…์‹œ์ ์œผ๋กœ ์จ์ฃผ์–ด์•ผ ํ•˜๋Š”์ง€ ๊ฐ์„ ์žก๊ฒŒ ๋œ๋‹ค.

์ธ์ž ์—†๋Š” ํ•จ์ˆ˜

ํ•จ์ˆ˜ re์™€ im์˜ ์‚ฌ์†Œํ•œ ๋ฌธ์ œ๋Š” ๊ทธ๋“ค์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ํ•ญ์ƒ ๋’ค์— ๋นˆ ๊ด„ํ˜ธ๋ฅผ ๋ถ™์—ฌ ์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์•„๋ž˜๋ฅผ ๋ณด์ž:

object ComplexNumbers {
  def main(args: Array[String]): Unit = {
    val c = new Complex(1.2, 3.4)
    println("imaginary part: " + c.im())
  }
}

์‹ค์ˆ˜ ๋ถ€๋ถ„๊ณผ ํ—ˆ์ˆ˜ ๋ถ€๋ถ„์— ์ ‘๊ทผ ํ•  ๋•Œ์— ๋งˆ์น˜ ๊ทธ๋“ค์ด ํ•„๋“œ์ธ ๊ฒƒ ์ฒ˜๋Ÿผ ํ•จ์ˆ˜ ๋งˆ์ง€๋ง‰์— ๋นˆ ๊ด„ํ˜ธ๋ฅผ ๋ถ™์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋”์šฑ ์ข‹๊ฒ ๋‹ค. ๋†€๋ผ์ง€ ๋งˆ์‹œ๋ผ, Scala๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ œ๊ณตํ•œ๋‹ค. ๊ทธ์ € ์ธ์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋ฉด ๋œ๋‹ค. ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ํ•จ์ˆ˜๋Š” ์ธ์ž๊ฐ€ 0๊ฐœ์ธ ํ•จ์ˆ˜์™€๋Š” ๋‹ค๋ฅธ๋ฐ, ์ธ์ž๊ฐ€ 0๊ฐœ์ธ ํ•จ์ˆ˜๋Š” ๋นˆ ๊ด„ํ˜ธ๊ฐ€ ๋”ฐ๋ผ ๋ถ™๋Š” ๋ฐ˜๋ฉด ์ด ํ•จ์ˆ˜๋Š” ์ •์˜ ํ•  ๋•Œ๋„ ์‚ฌ์šฉ ํ•  ๋•Œ๋„ ์ด๋ฆ„ ๋’ค์— ๊ด„ํ˜ธ๋ฅผ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์•ž์„œ ์ •์˜ํ•œ Complex ํด๋ž˜์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค์‹œ ์“ธ ์ˆ˜ ์žˆ๋‹ค:

class Complex(real: Double, imaginary: Double) {
  def re = real
  def im = imaginary
}

์ƒ์†๊ณผ ์žฌ์ •์˜

๋ชจ๋“  Scala์˜ ํด๋ž˜์Šค๋“ค์€ ํ•ญ์ƒ ์ƒ์œ„ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋œ๋‹ค. ๋งŒ์•ฝ Complex ์˜ˆ์ œ ์ฒ˜๋Ÿผ ์ƒ์œ„ ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ๋Š” ๋ฌต์‹œ์ ์œผ๋กœ scala.AnyRef๋ฅผ ์ƒ์†ํ•œ๋‹ค.

Scala์—์„œ๋Š” ๋ฌผ๋ก  ์ƒ์œ„ ํด๋ž˜์Šค์— ์ •์˜๋œ ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜๋„ํ•˜์ง€ ์•Š๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜๋Š” ํ•จ์ˆ˜๋Š” override ์ง€์‹œ์ž๋ฅผ ๊ผญ ์ ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ์šฐ๋ฆฌ์˜ Complex ํด๋ž˜์Šค์— ๋Œ€ํ•ด Object๋กœ ๋ถ€ํ„ฐ ์ƒ์†๋œ toString ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ ํ•˜๋Š” ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค:

class Complex(real: Double, imaginary: Double) {
  def re = real
  def im = imaginary
  override def toString() =
    "" + re + (if (im >= 0) "+" else "") + im + "i"
}

์ผ€์ด์Šค ํด๋ž˜์Šค ๊ทธ๋ฆฌ๊ณ  ํŒจํ„ด ๋งค์นญ

ํ”„๋กœ๊ทธ๋žจ์— ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์ค‘์˜ ํ•˜๋‚˜๋Š” ํŠธ๋ฆฌ์ด๋‹ค. ์ธํ„ฐํ”„๋ฆฌํ„ฐ์™€ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ”ํžˆ ํŠธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด๋ถ€ ํ‘œํ˜„์„ ์ €์žฅํ•˜๊ณ , XML ๋ฌธ์„œ๋„ ํŠธ๋ฆฌ์ด๋ฉฐ, ๋ ˆ๋“œ-๋ธ”๋ž™ ํŠธ๋ฆฌ์™€ ๊ฐ™์€ ์ €์žฅ๊ตฌ์กฐ๋“ค๋„ ํŠธ๋ฆฌ์— ๊ธฐ๋ฐ˜์„ ๋‘๊ณ  ์žˆ๋‹ค.

์ž‘์€ ๊ณ„์‚ฐ๊ธฐ ํ”„๋กœ๊ทธ๋žจ์„ ํ†ตํ•ด Scala์—์„œ ์ด๋Ÿฌํ•œ ํŠธ๋ฆฌ๋“ค์„ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•˜๊ณ  ๋‹ค๋ฃจ๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ์•„ ๋ณด์ž. ์ด ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชฉํ‘œ๋Š” ๋”ํ•˜๊ธฐ์™€ ์ƒ์ˆ˜์ธ ์ •์ˆ˜ ๊ทธ๋ฆฌ๊ณ  ๋ณ€์ˆ˜๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ„๋‹จํ•œ ์‚ฐ์ˆ  ํ‘œํ˜„์‹์„ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, 1+2๋‚˜ (x+x)+(7+y) ๊ฐ™์€ ์‹๋“ค ๋ง์ด๋‹ค.

์ฒ˜์Œ์œผ๋กœ, ์šฐ๋ฆฌ๋Š” ํ•ด๋‹น ์‚ฐ์ˆ  ํ‘œํ˜„์‹๋“ค์„ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ ํ• ์ง€ ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค. ๊ฐ€์žฅ ์ž์—ฐ์Šค๋Ÿฌ์šด ๋ฐฉ๋ฒ•์€ ํŠธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋…ธ๋“œ๋Š” ์—ฐ์‚ฐ(์—ฌ๊ธฐ์„œ๋Š” ๋ง์…ˆ)์ด ๋  ๊ฒƒ์ด๊ณ , ๋ฆฌํ”„๋Š” ๊ฐ’(์—ฌ๊ธฐ์„œ๋Š” ์ƒ์ˆ˜ ๋˜๋Š” ๋ณ€์ˆ˜)๊ฐ€ ๋˜๊ฒ ๋‹ค.

Java์˜€๋‹ค๋ฉด ํŠธ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด, ํŠธ๋ฆฌ์— ๋Œ€ํ•œ ์ถ”์ƒ ์ƒ์œ„ ํด๋ž˜์Šค์™€ ๋…ธ๋“œ์™€ ๋ฆฌํ”„ ๊ฐ๊ฐ์— ๋Œ€ํ•œ ์‹ค์ œ ํ•˜์œ„ ํด๋ž˜์Šค๋“ค์„ ์ •์˜ ํ–ˆ์„ ๊ฒƒ์ด๋‹ค. ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์˜€๋‹ค๋ฉด ๊ฐ™์€ ๋ชฉ์ ์œผ๋กœ ๋Œ€์ˆ˜์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์‚ฌ์šฉ ํ–ˆ์„ ๊ฒƒ์ด๋‹ค. Scala๋Š” ์ผ€์ด์Šค ํด๋ž˜์Šค๋ผ ํ•˜๋Š” ์ด ๋‘˜ ์‚ฌ์ด์˜ ์–ด๋””์ฏค์— ๋†“์—ฌ ์งˆ ์ˆ˜ ์žˆ๋Š” ์žฅ์น˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์šฐ๋ฆฌ ์˜ˆ์ œ์˜ ํŠธ๋ฆฌ ํƒ€์ž…์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ์ด ์žฅ์น˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ ๋˜๋Š”์ง€ ์•„๋ž˜์—์„œ ์‹ค์ œ์ ์ธ ์˜ˆ๋ฅผ ๋ณด์ž:

abstract class Tree
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree

ํด๋ž˜์Šค Sum, Var ๊ทธ๋ฆฌ๊ณ  Const๊ฐ€ ์ผ€์ด์Šค ํด๋ž˜์Šค๋กœ ์„ ์–ธ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์€ ์ด๋“ค์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฉด์—์„œ ์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค์™€ ๋‹ค๋ฅด๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค:

  • ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ ํ•  ๋•Œ new ํ‚ค์›Œ๋“œ๋ฅผ ์ƒ๋žต ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋ฅธ ๋ง๋กœ, new Const(5)๋ผ ์“ฐ๋Š” ๋Œ€์‹  Const(5)๋ผ ์“ฐ๋ฉด ๋œ๋‹ค.
  • ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์— ๋Œ€ํ•œ getter ํ•จ์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ์ •์˜๋œ๋‹ค. ๋‹ค๋ฅธ ๋ง๋กœ, ํด๋ž˜์Šค Const์˜ ์ธ์Šคํ„ด์Šค c์— ์žˆ๋Š” ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ v์˜ ๊ฐ’์€ c.v๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ•จ์ˆ˜ equals์™€ hashCode๋„ ๊ณต์งœ๋กœ ์ œ๊ณต๋œ๋‹ค. ์ด ํ•จ์ˆ˜๋“ค์€ ๋ ˆํผ๋Ÿฐ์Šค์˜ ๋™์ผํ•จ ๋ณด๋‹ค ๊ตฌ์กฐ์˜ ๋™์ผํ•จ์„ ํ™•์ธ ํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ๋‹ค๋ฅธ ๋ง๋กœ, ์ƒ์„ฑ ๋œ ๊ณณ์ด ๋‹ค๋ฅด๋”๋ผ๋„ ๊ฐ๊ฐ์˜ ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ์—ฌ๊ธด๋‹ค.
  • ํ•จ์ˆ˜ toString์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์  ๊ตฌํ˜„์ด ์ œ๊ณต๋œ๋‹ค. ์ด ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ˜„์€ โ€œ๊ฐ’์ด ์ƒ์„ฑ ๋  ๋•Œโ€์˜ ํ˜•ํƒœ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด x+1์˜ ํŠธ๋ฆฌ ํ‘œํ˜„ ์„ ์ถœ๋ ฅ ํ•œ๋‹ค๋ฉด Sum(Var(x),Const(1))์ด ๋œ๋‹ค.
  • ์ผ€์ด์Šค ํด๋ž˜์Šค๋“ค์˜ ์ธ์Šคํ„ด์Šค๋Š” ํŒจํ„ด ๋งค์นญ์„ ํ†ตํ•ด ๋”ฐ๋กœ ์‚ฌ์šฉ ๋  ์ˆ˜ ์žˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜์—์„œ ๋‹ค๋ฃฌ๋‹ค.

์‚ฐ์ˆ  ํ‘œํ˜„์‹์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ •์˜ ํ–ˆ์œผ๋ฏ€๋กœ ์ด์ œ ๊ทธ๊ฒƒ๋“ค์„ ๊ณ„์‚ฐ ํ•  ์—ฐ์‚ฐ์ž๋“ค์„ ์ •์˜ ํ•  ์ฐจ๋ก€๋‹ค. ์ผ๋‹จ, ์–ด๋–ค ํ™˜๊ฒฝ์•ˆ์—์„œ ํ‘œํ˜„์‹์„ ๊ณ„์‚ฐ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์ž. ํ™˜๊ฒฝ์€ ๊ฐ๊ฐ์˜ ๋ณ€์ˆ˜๋งˆ๋‹ค ์ฃผ์–ด์ง„ ๊ฐ’๋“ค์„ ์ €์žฅ ํ•ด ๋‘๋Š” ๊ณณ์ด๋‹ค. ์ปดํ“จํ„ฐ์—์„œ ๋ฉ”๋ชจ๋ฆฌ์˜ ์—ญํ• ๊ณผ ๋น„์Šท ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ณ€์ˆ˜ x์— 5๊ฐ€ ์ €์žฅ๋œ ํ™˜๊ฒฝ({ x -> 5 })์—์„œ ํ‘œํ˜„์‹ x+1์„ ๊ณ„์‚ฐํ•˜๋ฉด ๊ฒฐ๊ณผ๋กœ 6์ด ๋‚˜์˜จ๋‹ค.

ํ™˜๊ฒฝ์€ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•˜๋Š”๊ฒŒ ์ข‹์„๊นŒ? ๊ฐ„๋‹จํžˆ ์ƒ๊ฐํ•˜๋ฉด, ํ•ด์‰ฌ ํ…Œ์ด๋ธ” ๊ฐ™์€ ๋‘ ๊ฐ’์„ ๋ฌถ์–ด์ฃผ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ชฉ์ ์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ์‚ฌ์šฉ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค! ๊ฐ€๋งŒ ์ƒ๊ฐํ•ด ๋ณด๋ฉด ํ™˜๊ฒฝ์ด๋ผ๋Š” ๊ฒƒ์€ ๋ณ€์ˆ˜๋ช…์—์„œ ๊ฐ’์œผ๋กœ ๊ฐ€๋Š” ํ•จ์ˆ˜์— ์ง€๋‚˜์ง€ ์•Š๋Š”๋‹ค. ์œ„์—์„œ ์‚ฌ์šฉํ•œ ํ™˜๊ฒฝ { x -> 5 } ์€ Scala๋กœ ๊ฐ„๋‹จํžˆ ์•„๋ž˜์™€ ๊ฐ™์ด ์“ด๋‹ค:

{ case "x" => 5 }

์ด ๋ฌธ๋ฒ•์€ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋ฌธ์ž์—ด "x"๊ฐ€ ์ธ์ž๋กœ ๋“ค์–ด ์™”์„ ๋•Œ ์ •์ˆ˜ 5๋ฅผ ๋Œ๋ ค์ฃผ๊ณ , ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒฝ์šฐ์— ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํ•จ์ˆ˜์ด๋‹ค.

๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— ํ™˜๊ฒฝ ํƒ€์ž…์— ์ด๋ฆ„์„ ๋ถ™์—ฌ ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ๋‹ค. ๋ฌผ๋ก  ํ•ญ์ƒ ํ™˜๊ฒฝ ํƒ€์ž…์œผ๋กœ String => Int๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋˜์ง€๋งŒ ๋ณด๊ธฐ ์ข‹์€ ์ด๋ฆ„์„ ๋ถ™์ด๋Š” ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์„ ๋” ์ฝ๊ธฐ์— ๋ช…๋ฃŒํ•˜๊ณ  ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜๊ฒŒ ํ•ด ์ค€๋‹ค. Scala์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค:

type Environment = String => Int

์ด์ œ๋ถ€ํ„ฐ ํƒ€์ž… Environment๋Š” String์—์„œ Int๋กœ ๊ฐ€๋Š” ํ•จ์ˆ˜ ํƒ€์ž…์˜ ๋‹ค๋ฅธ ์ด๋ฆ„์ด๋‹ค.

์ง€๊ธˆ๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์ž. ๊ฐœ๋…์œผ๋กœ ๋”ฐ์ง€๋ฉด ๋งค์šฐ ๊ฐ„๋‹จํ•˜๋‹ค: ๋‘ ํ‘œํ˜„์‹์˜ ํ•ฉ์€ ๊ฐ ํ‘œํ˜„์‹์˜ ๊ฐ’์„ ๊ตฌํ•˜์—ฌ ๋”ํ•œ ๊ฒƒ์ด๋‹ค. ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ํ™˜๊ฒฝ์—์„œ ๋ฐ”๋กœ ๊ฐ€์ ธ ์˜ฌ ์ˆ˜ ์žˆ๊ณ , ์ƒ์ˆ˜์˜ ๊ฐ’์€ ์ƒ์ˆ˜ ์ž์ฒด์ด๋‹ค. ์ด๊ฒƒ์„ Scala๋กœ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์€ ์–ด๋ ต์ง€ ์•Š๋‹ค:

def eval(t: Tree, env: Environment): Int = t match {
  case Sum(l, r) => eval(l, env) + eval(r, env)
  case Var(n)    => env(n)
  case Const(v)  => v
}

์ด ๊ณ„์‚ฐ ํ•จ์ˆ˜๋Š” ํŠธ๋ฆฌ t์— ๋Œ€ํ•ด ํŒจํ„ด ๋งค์นญ์„ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ ๋™์ž‘ํ•œ๋‹ค. ์œ„์˜ ํ•จ์ˆ˜ ์ •์˜๋Š” ์ง๊ด€์ ์œผ๋กœ๋„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค:

  1. ์ฒ˜์Œ์œผ๋กœ t๊ฐ€ Sum์ธ์ง€ ํ™•์ธํ•œ๋‹ค. ๋งŒ์•ฝ ๋งž๋‹ค๋ฉด ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜ l์— ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜ r์— ํ• ๋‹น ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ™”์‚ดํ‘œ๋ฅผ ๋”ฐ๋ผ ํ™”์‚ดํ‘œ์˜ ์˜ค๋ฅธํŽธ์œผ๋กœ ๊ณ„์‚ฐ์„ ์ด์–ด ๋‚˜๊ฐ„๋‹ค. ํ™”์‚ดํ‘œ์˜ ์˜ค๋ฅธํŽธ์—์„œ๋Š” ํ™”์‚ดํ‘œ์˜ ์™ผํŽธ์—์„œ ํ• ๋‹น๋œ ๋ณ€์ˆ˜ l๊ณผ r์„ ์‚ฌ์šฉ ํ•œ๋‹ค.
  2. ์ฒซ๋ฒˆ์งธ ํ™•์ธ์ด ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•˜๋ฉด ํŠธ๋ฆฌ๋Š” Sum์ด ์•„๋‹ˆ๋ผ๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค. ๋‹ค์Œ์œผ๋กœ๋Š” t๊ฐ€ Var์ธ์ง€ ํ™•์ธํ•œ๋‹ค. ๋งŒ์•ฝ ๋งž๋‹ค๋ฉด Var ๋…ธ๋“œ ์•ˆ์— ํฌํ•จ๋œ ์ด๋ฆ„์„ ๋ณ€์ˆ˜ n์— ํ• ๋‹นํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ™”์‚ดํ‘œ์˜ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค.
  3. ๋‘๋ฒˆ์งธ ํ™•์ธ ์—ญ์‹œ ์‹คํŒจํ•˜๋ฉด t๋Š” Sum๋„ Var๋„ ์•„๋‹ˆ๋ผ๋Š” ๋œป์ด๋‹ค. ์ด์ œ๋Š” Const์— ๋Œ€ํ•ด ํ™•์ธ ํ•ด๋ณธ๋‹ค. ๋งŒ์•ฝ ๋งž๋‹ค๋ฉด Const ๋…ธ๋“œ ์•ˆ์˜ ๊ฐ’์„ ๋ณ€์ˆ˜ v์— ํ• ๋‹นํ•˜๊ณ  ํ™”์‚ดํ‘œ์˜ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ง„ํ–‰ํ•œ๋‹ค.
  4. ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ชจ๋“  ํ™•์ธ์ด ์‹คํŒจํ•˜๋ฉด ํŒจํ„ด ๋งค์นญ์ด ์‹คํŒจ ํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์€ ํ™•์ธ ํ•œ ๊ฒƒ ์™ธ์— Tree์˜ ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ๋” ์กด์žฌ ํ•  ๊ฒฝ์šฐ ์ผ์–ด๋‚œ๋‹ค.

ํŒจํ„ด ๋งค์นญ์˜ ๊ธฐ๋ณธ์ ์ธ ์•„์ด๋””์–ด๋Š” ๋Œ€์ƒ์ด ๋˜๋Š” ๊ฐ’์„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ด€์‹ฌ์žˆ๋Š” ํŒจํ„ด์— ๋Œ€ํ•ด ์ˆœ์„œ๋Œ€๋กœ ๋งž์ถฐ ๋ณธ ํ›„, ๋งž๋Š” ๊ฒƒ์ด ์žˆ์œผ๋ฉด ๋งž์€ ๊ฐ’ ์ค‘ ๊ด€์‹ฌ ์žˆ๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ƒˆ๋กญ๊ฒŒ ์ด๋ฆ„ ๋ถ™์ด๊ณ , ๊ทธ ์ด๋ฆ„ ๋ถ™์ธ ๋ถ€๋ถ„์„ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋– ํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ฐ์ฒด์ง€ํ–ฅ์— ์ˆ™๋ จ๋œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ผ๋ฉด ์™œ eval์„ ํด๋ž˜์Šค Tree์™€ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋กœ ์ •์˜ํ•˜์ง€ ์•Š์•˜๋Š”์ง€ ๊ถ๊ธˆ ํ•  ๊ฒƒ์ด๋‹ค. ์‚ฌ์‹ค ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์—ˆ๋‹ค. Scala๋Š” ์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค ์ฒ˜๋Ÿผ ์ผ€์ด์Šค ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋„ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค. ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋А๋ƒ ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋А๋ƒ๋Š” ์‚ฌ์šฉ์ž์˜ ์ทจํ–ฅ์— ๋‹ฌ๋ฆฐ ๋ฌธ์ œ๋‹ค. ํ•˜์ง€๋งŒ ํ™•์žฅ์„ฑ์— ๊ด€ํ•ด ์‹œ์‚ฌํ•˜๋Š” ์ค‘์š”ํ•œ ์ ์ด ์žˆ๋‹ค:

  • ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹จ์ง€ Tree์— ๋Œ€ํ•œ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ •์˜ ํ•จ์œผ๋กœ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‰ฝ๋‹ค. ๋ฐ˜๋ฉด์— ํŠธ๋ฆฌ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…์ด ๊ณ ๋˜๋‹ค. ์ƒˆ๋กœ์šด ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Tree์˜ ๋ชจ๋“  ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒํ™ฉ์ด ๋ฐ˜๋Œ€๊ฐ€ ๋œ๋‹ค. ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ํŠธ๋ฆฌ์— ๋Œ€ํ•ด ํŒจํ„ด ๋งค์นญ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๋“ค์„ ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋„ ๊ณ ๋ คํ•˜๋„๋ก ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค. ๋ฐ˜๋ฉด์— ์ƒˆ๋กœ์šด ์—ฐ์‚ฐ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ๋‹ค. ๊ทธ๋ƒฅ ์ƒˆ๋กœ์šด ๋…๋ฆฝ์ ์ธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.

ํŒจํ„ด ๋งค์นญ์— ๋Œ€ํ•ด ์ข€ ๋” ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด, ์‚ฐ์ˆ  ํ‘œํ˜„์‹์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์„ ์ •์˜ ํ•ด๋ณด์ž. ์ด๋ฒˆ ์—ฐ์‚ฐ์€ ์‹ฌ๋ณผ ์ถ”์ถœ์ด๋‹ค. ํŠธ๋ฆฌ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ํŠน์ • ๋ณ€์ˆ˜๋งŒ 1๋กœ ํ‘œ์‹œํ•˜๋Š” ์ผ์ด๋‹ค. ๋…์ž๋Š” ์•„๋ž˜ ๊ทœ์น™๋งŒ ๊ธฐ์–ตํ•˜๋ฉด ๋œ๋‹ค:

  1. ๋”ํ•˜๊ธฐ ํ‘œํ˜„์‹์—์„œ์˜ ์‹ฌ๋ณผ ์ถ”์ถœ์€ ์ขŒ๋ณ€๊ณผ ์šฐ๋ณ€์˜ ์‹ฌ๋ณผ์„ ์ถ”์ถœํ•˜์—ฌ ๋”ํ•œ ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.
  2. ๋ณ€์ˆ˜ v์— ๋Œ€ํ•œ ์‹ฌ๋ณผ ์ถ”์ถœ์€ v๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์ถ”์ถœํ•˜๊ธฐ ์›ํ•˜๋Š” ์‹ฌ๋ณผ๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค๋ฉด 1์ด ๋˜๊ณ  ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ 0์ด ๋œ๋‹ค.
  3. ์ƒ์ˆ˜์— ๋Œ€ํ•œ ์‹ฌ๋ณผ ์ถ”์ถœ ๊ฐ’์€ 0์ด๋‹ค.

์ด ๊ทœ์น™๋“ค์€ ๊ฑฐ์˜ ๊ทธ๋Œ€๋กœ Scala ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.

def derive(t: Tree, v: String): Tree = t match {
  case Sum(l, r) => Sum(derive(l, v), derive(r, v))
  case Var(n) if (v == n) => Const(1)
  case _ => Const(0)
}

์œ„์˜ ํ•จ์ˆ˜๋Š” ํŒจํ„ด ๋งค์นญ์— ๊ด€ํ•œ ๋‘ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์†Œ๊ฐœํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋กœ, case ํ‘œํ˜„์€ ๊ฐ€๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€๋“œ๋ž€ if ํ‚ค์›Œ๋“œ ๋’ค์— ์˜ค๋Š” ํ‘œํ˜„์‹์„ ๋œปํ•˜๋Š” ๋ง๋กœ ํŒจํ„ด ๋งค์นญ์— ์ถ”๊ฐ€์ ์ธ ์กฐ๊ฑด์„ ๋ถ€์—ฌํ•œ๋‹ค. ๊ฐ€๋“œ๊ฐ€ ์ฐธ์ด ๋˜์ง€ ์•Š์œผ๋ฉด ํŒจํ„ด ๋งค์นญ์€ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š”, ๋งค์นญ ๋œ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์ด ์šฐ๋ฆฌ๊ฐ€ ์ถ”์ถœํ•˜๋Š” ์‹ฌ๋ณผ v์™€ ๊ฐ™์„ ๋•Œ๋งŒ ์ƒ์ˆ˜ 1์„ ๋ฆฌํ„ดํ•จ์„ ๋ณด์žฅํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€ ์™€์ผ๋“œ์นด๋“œ์ด๋‹ค. ๋ฐ‘์ค„ ๋ฌธ์ž _๋กœ ์“ฐ๋ฉฐ, ๋ชจ๋“  ๊ฐ’๊ณผ ๋งค์น˜ ๋˜๊ณ  ๋”ฐ๋กœ ์ด๋ฆ„์„ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค.

ํŒจํ„ด ๋งค์นญ์˜ ๋›ฐ์–ด๋‚œ ๊ธฐ๋Šฅ๋“ค์„ ๋ชจ๋‘ ์‚ดํŽด๋ณด์ง€๋Š” ๋ชปํ–ˆ์ง€๋งŒ, ๋ฌธ์„œ๋ฅผ ๋„ˆ๋ฌด ์ง€๋ฃจํ•˜๊ฒŒ ๋งŒ๋“ค์ง€ ์•Š๊ธฐ ์œ„ํ•˜์—ฌ ์ด์ฏค์—์„œ ๋ฉˆ์ถ”๊ธฐ๋กœ ํ•œ๋‹ค. ์ด์ œ ์œ„์—์„œ ์ •์˜ํ•œ ๋‘ ๊ฐœ์˜ ์˜ˆ์ œ ํ•จ์ˆ˜๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๋ชจ์Šต์„ ๋ณด์ž. ์‚ฐ์ˆ  ํ‘œํ˜„์‹ (x+x)+(7+y)์— ๋Œ€ํ•ด ๋ช‡๊ฐ€์ง€์˜ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฐ„๋‹จํ•œ main ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ธฐ๋กœ ํ•œ๋‹ค. ์ฒซ๋ฒˆ์งธ๋กœ ํ™˜๊ฒฝ { x -> 5, y -> 7 }์—์„œ ๊ทธ ๊ฐ’์„ ๊ณ„์‚ฐ ํ•  ๊ฒƒ์ด๊ณ , ๋‹ค์Œ์œผ๋กœ x์™€ y์— ๋Œ€ํ•œ ์‹ฌ๋ณผ ์ถ”์ถœ์„ ์ˆ˜ํ–‰ ํ•  ๊ฒƒ์ด๋‹ค.

def main(args: Array[String]): Unit = {
  val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))
  val env: Environment = { case "x" => 5 case "y" => 7 }
  println("Expression: " + exp)
  println("Evaluation with x=5, y=7: " + eval(exp, env))
  println("Derivative relative to x:\n " + derive(exp, "x"))
  println("Derivative relative to y:\n " + derive(exp, "y"))
}

์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด, ์˜ˆ์ƒ๋œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค:

Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y)))
Evaluation with x=5, y=7: 24
Derivative relative to x:
 Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0)))
Derivative relative to y:
 Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))

์ถœ๋ ฅ์„ ์‚ดํŽด ๋ณด๋ฉด ์‹ฌ๋ณผ ์ถ”์ถœ์˜ ๊ฒฐ๊ณผ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ข€ ๋ณต์žกํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ฒฐ๊ณผ๋ฅผ ๋‹จ์ˆœํ™” ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ์žฌ๋ฏธ์žˆ๋Š” ๋ฌธ์ œ์ด๋‹ค(์ƒ๊ฐ๋ณด๋‹ค ๋ณต์žกํ•˜๊ธฐ๋„ ํ•˜๋‹ค). ๋…์ž๋“ค์—๊ฒŒ ์—ฐ์Šต๋ฌธ์ œ๋กœ ๋‚จ๊ฒจ๋‘๊ฒ ๋‹ค.

ํŠธ๋ ˆ์ž‡์— ๋Œ€ํ•˜์—ฌ

Scala ํด๋ž˜์Šค์—์„œ๋Š” ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ์ฝ”๋“œ๋ฅผ ์ƒ์† ๋ฐ›๋Š” ๊ฒƒ ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ, ํ•˜๋‚˜ ๋˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŠธ๋ ˆ์ž‡(trait)์—์„œ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

Java ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์ด ํŠธ๋ ˆ์ž‡์„ ์ดํ•ดํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๊ธธ์€ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Scala์—์„œ ์–ด๋–ค ํด๋ž˜์Šค๊ฐ€ ํŠธ๋ ˆ์ž‡์„ ์ƒ์†ํ•˜๋ฉด, ๊ทธ ํด๋ž˜์Šค๋Š” ํŠธ๋ ˆ์ž‡์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ๋งŒ ํ•˜๊ณ  ๋™์‹œ์— ํŠธ๋ ˆ์ž‡์ด ๊ฐ€์ง„ ๋ชจ๋“  ์ฝ”๋“œ๋“ค์„ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋œ๋‹ค.

ํŠธ๋ ˆ์ž‡์˜ ์œ ์šฉํ•จ์„ ๋ณด์ด๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๋“ค์— ์ˆœ์„œ๋ฅผ ๋ถ™์ด๋Š” ๊ณ ์ „์ ์ธ ์˜ˆ์ œ ํ•˜๋‚˜๋ฅผ ๋“ค์–ด๋ณด๊ธฐ๋กœ ํ•˜์ž. ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋“ค์€ ์ •๋ ฌ๋ฌธ์ œ ์ฒ˜๋Ÿผ ์ฃผ๋กœ ๊ทธ๋“ค ์‚ฌ์ด์— ๋น„๊ต๊ฐ€ ํ•„์š” ํ•  ๊ฒฝ์šฐ ์œ ์šฉํ•˜๋‹ค. Java์—์„œ๋Š” ๋น„๊ต๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋“ค์ด Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋œ๋‹ค. Scala์—์„œ๋Š” ์ด Comparable์„ ํŠธ๋ ˆ์ž‡์œผ๋กœ ์ •์˜ํ•˜์—ฌ ๋” ๋‚˜์€ ํ”„๋กœ๊ทธ๋žจ ๋””์ž์ธ์„ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์ด๋ฅผ Ord๋ผ ๋ถ€๋ฅผ ๊ฒƒ์ด๋‹ค.

๊ฐ์ฒด๋ฅผ ๋น„๊ต ํ•  ๋•Œ, ์—ฌ์„ฏ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๊ด€๊ณ„๊ฐ€ ์ฃผ๋กœ ์‚ฌ์šฉ ๋œ๋‹ค: ์ž‘๋‹ค, ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค, ๊ฐ™๋‹ค, ๊ฐ™์ง€ ์•Š๋‹ค, ํฌ๊ฑฐ๋‚˜ ๊ฐ™๋‹ค, ํฌ๋‹ค. ํ•˜์ง€๋งŒ ์ด ์—ฌ์„ฏ๊ฐœ๋ฅผ ์ผ์ผํžˆ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์ง€๋ฃจํ•˜๊ณ  ์˜๋ฏธ ์—†๋Š” ์ผ์ด ๋  ๊ฒƒ์ด๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์ด์ค‘ ๋‘ ๊ฐ€์ง€ ๊ด€๊ณ„๋งŒ ์ •์˜ ๋˜์–ด๋„ ๋‚˜๋จธ์ง€ ๋„ค๊ฐ€์ง€ ๊ด€๊ณ„๋ฅผ ๊ณ„์‚ฐ ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์€๊ฐ€. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ™๋‹ค์™€ ์ž‘๋‹ค๋งŒ ๊ฒฐ์ • ํ•  ์ˆ˜ ์žˆ์–ด๋„ ๋‚˜๋จธ์ง€ ๊ด€๊ณ„์˜ ์ฐธ ๊ฑฐ์ง“์„ ์‰ฝ๊ฒŒ ํŒ๋‹จ ํ•  ์ˆ˜ ์žˆ๋‹ค. Scala์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋…ผ๋ฆฌ๋“ค์„ ํŠธ๋ ˆ์ž‡์˜ ์ •์˜ ์•ˆ์— ์šฐ์•„ํ•˜๊ฒŒ ํ‘œํ˜„ ํ•ด ๋‚ผ ์ˆ˜ ์žˆ๋‹ค:

trait Ord {
  def < (that: Any): Boolean
  def <=(that: Any): Boolean =  (this < that) || (this == that)
  def > (that: Any): Boolean = !(this <= that)
  def >=(that: Any): Boolean = !(this < that)
}

์œ„์˜ ์ •์˜๋Š” Java์˜ Comparable ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•˜๋Š” Ord๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ๋งŒ๋“ ๋‹ค. ์ด ์ƒˆ๋กœ์šด ํƒ€์ž…์—๋Š” ์„ธ๊ฐ€์ง€์˜ ๊ด€๊ณ„์‹์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ตฌํ˜„์ด ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ด ๊ตฌํ˜„์€ ๋ชจ๋‘ ํ•˜๋‚˜์˜ ์ถ”์ƒ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด์— ๋Œ€ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์กด์žฌํ•˜๋Š” ๊ฐ™๋‹ค์™€ ๊ฐ™์ง€ ์•Š๋‹ค์— ๋Œ€ํ•œ ๊ด€๊ณ„์‹์€ ๋น ์ ธ ์žˆ๋‹ค.

์œ„์—์„œ ์‚ฌ์šฉ๋œ ํƒ€์ž… Any๋Š” Scala์˜ ์ตœ์ƒ์œ„ ํƒ€์ž…์ด๋‹ค. Java์˜ Object ํƒ€์ž…๊ณผ ๊ฐ™์œผ๋‚˜, Int, Float๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ํƒ€์ž…์˜ ์ƒ์œ„ ํƒ€์ž…์ด๋ผ๋Š” ์ ์—์„œ ์ข€ ๋” ์ผ๋ฐ˜ํ™” ๋œ ๋ฒ„์ „์ด๋ผ ์ƒ๊ฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ์ฒด๋ฅผ ๋น„๊ต ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ •์˜ํ•ด์•ผ ํ•  ๊ฒƒ์€ ๊ฐ™๋‹ค์™€ ์ž‘๋‹ค ๋ฟ์ด๋‹ค. ๋‚˜๋จธ์ง€๋Š” ์œ„์˜ Ord ํŠธ๋ ˆ์ž‡์„ ์‚ฝ์ž…ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค. ํ•˜๋‚˜์˜ ์˜ˆ๋กœ ๊ทธ๋ ˆ๊ณ ๋ฆฌ๋ ฅ์˜ ๋‚ ์งœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Date ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž. ์ด ๋‚ ์งœ๋Š” ์ •์ˆ˜์ธ ๋‚ , ์›”, ๋…„์œผ๋กœ ๊ตฌ์„ฑ ๋œ๋‹ค. ์ผ๋‹จ ์•„๋ž˜์ฒ˜๋Ÿผ ๋งŒ๋“ ๋‹ค:

class Date(y: Int, m: Int, d: Int) extends Ord {
  def year = y
  def month = m
  def day = d
  override def toString(): String = s"$year-$month-$day"

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ํด๋ž˜์Šค ์ด๋ฆ„๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ ๋’ค์— ๋”ฐ๋ผ์˜ค๋Š” extends Ord ์„ ์–ธ์ด๋‹ค. ์ด ์„ ์–ธ์€ Date ํด๋ž˜์Šค๊ฐ€ Ord ํŠธ๋ ˆ์ž‡์„ ์ƒ์†ํ•จ์„ ๋œปํ•œ๋‹ค.

๋‹ค์Œ์œผ๋กœ Object์—์„œ ์ƒ์†๋œ equals ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ ํ•˜์—ฌ ๊ฐ๊ฐ์˜ ์ผ, ์›”, ๋…„์„ ๋น„๊ตํ•˜์—ฌ ๊ฐ™์Œ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํŒ๋‹จํ•˜๋„๋ก ํ•œ๋‹ค. equals์˜ ๊ธฐ๋ณธ ์ •์˜๋Š” ์“ธ๋ชจ๊ฐ€ ์—†๋‹ค. ์™œ๋ƒํ•˜๋ฉด Java์™€ ๊ฐ™์ด ๊ธฐ๋ณธ์ ์ธ equals๋Š” ๋ฌผ๋ฆฌ์  ์ฃผ์†Œ๋ฅผ ๋น„๊ตํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ตœ์ข…์ ์ธ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

override def equals(that: Any): Boolean =
  that.isInstanceOf[Date] && {
    val o = that.asInstanceOf[Date]
    o.day == day && o.month == month && o.year == year
  }

์ด ํ•จ์ˆ˜๋Š” ๋ฏธ๋ฆฌ ์ •์˜๋œ ํ•จ์ˆ˜์ธ isInstanceOf์™€ asInstanceOf๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ฒซ๋ฒˆ์งธ isInstanceOf๋Š” Java์˜ instanceof ์—ฐ์‚ฐ์ž์™€ ๋™์ผํ•œ ์ผ์„ ํ•œ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ ๋œ ๊ฐ์ฒด๊ฐ€ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋“ค์–ด์˜จ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค์ด๋ฉด ์ฐธ์„ ๋ฆฌํ„ดํ•œ๋‹ค. ๋‘๋ฒˆ์งธ asInstanceOf๋Š” Java์˜ ์บ์ŠคํŠธ ์—ฐ์‚ฐ์ž์™€ ๋™์ผํ•˜๋‹ค. ํ˜ธ์ถœ ๋œ ๊ฐ์ฒด๊ฐ€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค์ด๋ฉด ๊ทธ๋ ‡๊ฒŒ ์—ฌ๊ฒจ์ง€๋„๋ก ๋ณ€ํ™˜ํ•˜๊ณ  ์•„๋‹ˆ๋ผ๋ฉด ClassCastException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

์•„๋ž˜ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ •์˜๋œ ํ•จ์ˆ˜๋Š” ์ž‘์Œ์„ ํŒ๋‹จํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” error๋ผ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฏธ๋ฆฌ ์ •์˜๋œ ํ•จ์ˆ˜๊ฐ€ ์“ฐ์˜€๋Š”๋ฐ, ์ด ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

def <(that: Any): Boolean = {
  if (!that.isInstanceOf[Date])
    error("cannot compare " + that + " and a Date")

  val o = that.asInstanceOf[Date]
  (year < o.year) ||
  (year == o.year && (month < o.month ||
                     (month == o.month && day < o.day)))
}

์ด๊ฑธ๋กœ Date ํด๋ž˜์Šค์˜ ์ •์˜๊ฐ€ ์™„์„ฑ๋˜์—ˆ๋‹ค. ์ด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ๋‚ ์งœ๋กœ๋„ ๋˜๋Š” ๋น„๊ต๊ฐ€๋Šฅํ•œ ์–ด๋–ค ๊ฐ์ฒด๋กœ๋„ ์—ฌ๊ฒจ์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๋“ค์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์—ฌ์„ฏ๊ฐ€์ง€ ๋น„๊ต์—ฐ์‚ฐ์„ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, equals์™€ <๋Š” Date ํด๋ž˜์Šค์˜ ์ •์˜ ์•ˆ์— ์ง์ ‘ ๊ตฌํ˜„๋˜์–ด ์žˆ๊ณ  ๋‚˜๋จธ์ง€๋Š” Ord ํŠธ๋ ˆ์ž‡์—์„œ ์ƒ์† ๋ฐ›์€ ๊ฒƒ์ด๋‹ค.

ํŠธ๋ ˆ์ž‡์€ ์—ฌ๊ธฐ์„œ ์˜ˆ๋กœ ๋“  ๊ฒฝ์šฐ ์™ธ์—๋„ ๋ฌผ๋ก  ๋‹ค์–‘ํ•˜๊ฒŒ ์‚ฌ์šฉ ๋  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ๋“ค์— ๋Œ€ํ•˜์—ฌ ๊นŠ๊ฒŒ ๋‹ค๋ฃจ๋Š” ์ผ์€ ์ด ๋ฌธ์„œ์˜ ๋ฒ”์œ„ ๋ฐ–์ด๋‹ค.

์ œ๋„ค๋ฆญํ•จ

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ ๋‹ค๋ฃฐ Scala์˜ ๋งˆ์ง€๋ง‰ ํŠน์ง•์€ ์ œ๋„ค๋ฆญํ•จ์ด๋‹ค. Java ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์€ Java์˜ ์ œ๋„ค๋ฆญ ์ง€์›์ด ๋ถ€์กฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฌธ์ œ์ ๋“ค์— ๋Œ€ํ•ด ์ž˜ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด ๋ฌธ์ œ์ ๋“ค์€ Java 1.5์—์„œ ๋‹ค๋ค„์กŒ๋‹ค.

์ œ๋„ค๋ฆญํ•จ์ด๋ž€ ์ฝ”๋“œ๋ฅผ ํƒ€์ž…์— ๋Œ€ํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์ด๋‹ค. ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ํ•˜๋‚˜์˜ ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณด์ž. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์›์†Œ ํƒ€์ž…์„ ๋„๋Œ€์ฒด ๋ฌด์—‡์œผ๋กœ ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผ์— ๋น ์ง€๊ฒŒ ๋œ๋‹ค. ์ด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋งŽ์€ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์›์†Œ์˜ ํƒ€์ž…์ด ๋ฐ˜๋“œ์‹œ Int ๋˜๋Š” ๋ฐ˜๋“œ์‹œ Double์ด ๋  ๊ฒƒ์ด๋ผ ๋ฏธ๋ฆฌ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋ ‡๊ฒŒ ๊ฒฐ์ •ํ•ด ๋‘๋Š” ์ผ์€ ์™„์ „ํžˆ ์ž„์˜์ ์ด๋ฉฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์— ์žˆ์–ด ํ•„์š” ์ด์ƒ์˜ ์‹ฌํ•œ ์ œ์•ฝ์œผ๋กœ ์ž‘์šฉ ํ•œ๋‹ค.

Java ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์–ด์ฉ” ์ˆ˜ ์—†์ด Object๋ฅผ ์‚ฌ์šฉํ•˜๊ณค ํ•œ๋‹ค. Object๋Š” ๋ชจ๋“  ๊ฐ์ฒด์˜ ์ƒ์œ„ ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์€ ์ด์ƒ์ ์ด์ง€ ์•Š๋‹ค. int, long, float๋“ฑ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ํƒ€์ž…์— ๋Œ€ํ•ด ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—์„œ ์›์†Œ๋ฅผ ๊ฐ€์ ธ ์˜ฌ ๋•Œ๋งˆ๋‹ค ๋งŽ์€ ๋™์  ํƒ€์ž… ์บ์ŠคํŠธ๋“ค์„ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ์‚ฝ์ž…ํ•ด ์ฃผ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Scala๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค์™€ ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•œ๋‹ค. ์˜ˆ์ œ๋กœ ํ•จ๊ป˜ ์‚ดํŽด๋ณด์ž. ์˜ˆ์ œ๋Š” ๋ ˆํผ๋Ÿฐ์Šค๋ผ๋Š” ๊ฐ„๋‹จํ•œ ์ €์žฅ๊ตฌ์กฐ ํด๋ž˜์Šค์ด๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ๋น„์–ด์žˆ๊ฑฐ๋‚˜ ๋˜๋Š” ์–ด๋–ค ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๊ฐ€ ๋œ๋‹ค.

class Reference[T] {
  private var contents: T = _
  def set(value: T) { contents = value }
  def get: T = contents
}

ํด๋ž˜์Šค Reference๋Š” ํƒ€์ž… T์— ๋Œ€ํ•ด ํŒŒ๋ผ๋ฏธํ„ฐํ™” ๋˜์–ด์žˆ๋‹ค. ํƒ€์ž… T๋Š” ๋ ˆํผ๋Ÿฐ์Šค์˜ ์›์†Œ ํƒ€์ž…์ด๋‹ค. ์ด ํƒ€์ž…์€ ํด๋ž˜์Šค ๋‚ด๋ถ€ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ๋‚˜ํƒ€๋‚˜๋Š”๋ฐ, contents ๋ณ€์ˆ˜์˜ ํƒ€์ž…์œผ๋กœ, set ํ•จ์ˆ˜์˜ ์ธ์ž ํƒ€์ž…์œผ๋กœ, ๊ทธ๋ฆฌ๊ณ  get ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉ ๋œ๋‹ค.

์œ„์˜ ์ฝ”๋“œ ์ƒ˜ํ”Œ์€ Scala์—์„œ ํ•„๋“œ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๋‚ด์šฉ์ด๋ฏ€๋กœ ๋”ฐ๋กœ ์„ค๋ช…์ด ํ•„์š” ์—†๋‹ค. ํ•œ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ์ ์ด ์žˆ๋‹ค๋ฉด ๋ณ€์ˆ˜์˜ ์ดˆ๊ธฐ๊ฐ’์ด _๋กœ ์ฃผ์–ด์ ธ ์žˆ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ, ์—ฌ๊ธฐ์„œ _๋Š” ๊ธฐ๋ณธ๊ฐ’์„ ๋œปํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ์ˆ˜ ํƒ€์ž…์— ๋Œ€ํ•ด์„œ 0, Boolean ํƒ€์ž…์— ๋Œ€ํ•ด์„œ false, Unit ํƒ€์ž…์— ๋Œ€ํ•ด (), ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ๊ฐ์ฒด ํƒ€์ž…์— ๋Œ€ํ•ด null์ด๋‹ค.

Reference ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ T์— ๋Œ€ํ•ด ์ ๋‹นํ•œ ํƒ€์ž…์„ ์ง€์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด ํƒ€์ž…์€ ๋ ˆํผ๋Ÿฐ์Šค ์•ˆ์— ๋“ค์–ด๊ฐˆ ์›์†Œ์˜ ํƒ€์ž…์ด ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ •์ˆ˜ ๊ฐ’์„ ์ €์žฅ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ด๋‹ค:

object IntegerReference {
  def main(args: Array[String]): Unit = {
    val cell = new Reference[Int]
    cell.set(13)
    println("Reference contains the half of " + (cell.get * 2))
  }
}

์œ„ ์˜ˆ์ œ์—์„œ ๋ณด๋“ฏ get ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์„ ์ •์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋”ฐ๋กœ ์บ์ŠคํŒ…์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. ์—ฌ๊ธฐ์„œ ์ •์˜๋œ ๋ ˆํผ๋Ÿฐ์Šค๋Š” ์ •์ˆ˜๋ฅผ ํฌํ•จํ•˜๋„๋ก ์„ ์–ธ์ด ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ •์ˆ˜ ์™ธ์— ๋‹ค๋ฅธ ๊ฒƒ์€ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค.

๋งˆ์น˜๋ฉฐ

์šฐ๋ฆฌ๋Š” ์ง€๊ธˆ๊นŒ์ง€ Scala ์–ธ์–ด์˜ ๊ฐ„๋žตํ•œ ์†Œ๊ฐœ์™€ ๋ช‡๊ฐ€์ง€์˜ ์˜ˆ์ œ๋ฅผ ์‚ดํŽด ๋ณด์•˜๋‹ค. ํฅ๋ฏธ๊ฐ€ ์ƒ๊ฒผ๋‹ค๋ฉด Tour of Scala๋„ ํ•จ๊ป˜ ์ฝ์–ด๋ณด์ž. ๋” ์ˆ˜์ค€ ๋†’๊ณ  ๋‹ค์–‘ํ•œ ์˜ˆ์ œ๋ฅผ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋‹ค. ํ•„์š” ํ•  ๋•Œ๋งˆ๋‹ค Scala Language Specification์„ ์ฐธ๊ณ ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹๋‹ค.

Contributors to this page: