터미널에서 스칼라 파일 직접 컴파일, 실행

항상 sbt나 eclipse 파일 받아서 실행시키다 보니 처음부터 만드는 방법을 아직 모르고 있다. 일단 컴파일및 실행. scalac -classpath ".:/외부라이브러리패스/*" demo.scala scala 클래스이름 스칼라의 기본 라이브러리만 사용하는 경우에는 classpath를 지정할 필요없지만 외부 자바라이브러리라도 사용하려면 위와 같이 지정해주어야 한다. 쌍따옴표(")를 사용하지 않으면 IO에러가 발생하며 *.jar와 같이 지정해 주어도 제대로 찾지 못한다. 앞의 '.'를 지정하지 않으면 scala 실행시 현재 디렉토리에서 클래스를 찾지 않는다. 반복적으로 사용하는 경우 .bash_profile에 다음과 같이 환경변수로 지정 export CLASSPATH=".:/외부라이브러리패스/*"

그 외 scala에서 함수 정의하기

def f1 = "Hello, world" def f2 = { "Hello, world" } def f3() = "Hello, world" def f4()() = "Hello, world" def f5 = () => "Hello, world" def f6() = () => "Hello, world" def f7 = () => ( () => "Hello, world" ) def f8(c: =>String) = c def f9(c: =>String) = () => c f1을 정의하고 나면 다음에 f1을 만날 때 "Hello, world"로 대치된다. f2는 f1과 동일하게 동작한다. {}안에는 여러 식을 사용할 수 있으며 마지막 식이 전체의 값이 된다. f3는 f1과 동일하다. 괄호없이 단순히 f3로 적어도 "Hello, world"값이 대치되며 f3()로 적어도 된다. f4는 f1, f3와 동일하게 사용할 수 있으나 f4, f4(), f4()() 모두 "Hello, world" 문자열로 대치된다. REPL에서 식을 입력해 보면 f1, f2는 String이지만 f3는 ()String f4는 ()()String이다. 일종의 currying이 아닐까 싶은데 인자가 없기 때문에 그냥 함수 이름만 적어도 여러 단계를 한번에 확장해 버리는 것 같다. f5의 type은 () => String이다. 다시 말해 f5는 아무런 인자도 가지지 않고 문자열을 반환하는 함수로 대치된다. 단순히 f5로 적으면 type과 함수임을 보여주며 실행시키려면 f5()와 같이 명시적으로 실행시켜야 한다. f6의 type은 ()() => String이며 단순히 f6를 입력하면 f5와 동일하게 보이나 f6()를 입력하면 문자열이 바로 반환되지 않으며 f6()()와 같이 ...

Scala에서의 9가지 함수 정의

def f1(n:Int) = println(n) def f2 = (n:Int) => println(n) 오랫만에 scalafx를 만져보다 위의 차이점에 대해 궁금하게 되었다. 결론부터 이야기하자면 f1은 하나의 정수 인자를 받아 출력하는 함수이며 f2는 하나의 정수인자를 받아 출력하는 함수를 반환하는 함수이다. f1의 type은 Int=>Unit이며 f2는 ()=>(Int=>Unit)이 되는 셈이다. StackOverflow 에는 Scala에서 함수를 정의하는 9가지 방법이라는 질문이 나와있다. def f1 = 10 def f2 {10} def f3 = {10} def f4() = 10 def f5() {10} def f6() = {10} def f7 = () => 10 def f8 = () => {10} def f9 = {() => {10}} 가장 좋은 평가를 받은 답을 간단히 요약하면 =을 사용하지 않은 함수 def는 Unit을 반환 하게 되므로 f1과 f5는 같은 함수이고 f2, f3, f4, f6는 아무런 인자를 가지지 않고 정수값을 반환하는 동일한 함수들이며 f7, f8, f9는 아무런 인자를 가지지 않고 정수값을 반환하는 함수를 반환하는 동일한 함수들이 된다. scalafx에서 이벤트 핸들러는 다음과 같이 실행하는데 keyHandler2를 keyHandler1과 같이 사용하지 못하는 이유를 찾아보다 알게 되었다. keyHandler2를 쓰려면 keyHandler2를 반환하는 handler2Wrapper와 같은 함수를 이용해야 한다. scene = new Scene { onKeyPressed = keyHandler1 } def keyHandler1 = (e:KeyEvent) => println(e.code) def keyHandler2(e:KeyEvent) = println(e.code) def handler2Wrapper:KeyEven...

아이맥 구입

이미지
얼마전 업데이트된 하스웰 기반의 아이맥을 구입하였습니다. 데스크 탑에서는 하스웰의 잇점이 거의 없다고 하지만 푸젼 드라이브를 설치했으니 부팅속도에서 잇점이 있을것 같습니다. 지금까지 쓰고 있던 맥은 2006년 하반기 구입. 7년이 지나다보니 더 이상 OS 업데이트도 되지 않는 지경에다 함께 사용하고 있던 NAS가 조금씩 정신이 왔다갔다 하는 바람에 새 모델 나오기를 기다렸다 구입했습니다. 근데 한참동안 꺼두었던 NAS가 제대로 동작하지 않는 문제에 봉착했네요. 이녀석 거의 사망직전인듯 합니다. 블랙박스같이 되어 있어서 문제없이 사용할 때는 편리하지만 문제가 발생한 경우 외부에서 접근할 수 있는 한두가지 방법이 통하지 않으면 도대체 무슨 문제인지 에러 메시지나 로그도 볼 수 없는게 단점이군요. 자료는 정신이 오락가락 할때 외장하드에 백업해 놓았습니다만 이걸 사용한다면 Aperture나 iTunes의 태그 같은 걸 새로 지정해야 할것 같으니 머리가 지끈 아프네요. 얼른 무사히 자료 이전이 끝나면 좋겠습니다. 그리고 개인적으로 NAS를 자료 저장소와 백업을 함께 하는 용도로 사용하지는 않아야 한다는 것을 알게 되었습니다. 하드 한개가 고장나는 경우 자료를 복구할 수 있지만 NAS 자체가 고장나면 결국 무용지물이 되니까요.

루빅스 큐브 기본

완전 초짜들을 위한 가이드 에 의하면 루빅스 큐브는 가운데에 고정되어 있는 1개의 면을 가지는 6큐브를 중심으로 2개의 면을 가지는 에지 큐브가 12개와 3개의 면을 가지는 모서리 큐브 8개가 모여서 이루어진다. 결국 주사위와 마찬가지로 축을 이루는 색깔간의 관계는 바뀌지 않고 에지와 모서리 큐브의 위치에 따라 상태(state)가 결정되는 셈이다. 어쩌면 큐브를 푸는 프로그램을 만들어 볼 수 있을것 같다.

scala에서 processing 사용하기

Scala에서 processing을 사용하는 예제들이 있는데 시험해 보면 size 명령이 제대로 동작하지 않는 경우가 있다. 보통 첫번째 방법을 많이 사용하는데 setup에서 size 명령이 제대로 먹히지 않는 반면 두번째 방법을 사용하니 제대로 동작한다. Windows 시스템에 한정된 일인지는 명확하지 않다. import processing.core._ object Test extends PApplet { private var test:Test = _ def main(args: Array[String]) = { test = new Test val frame = new javax.swing.JFrame("Test") frame.getContentPane().add(test) test.init frame.pack frame.setVisible(true) } } class Test extends PApplet { override def setup() = { } override def draw() = { } } import processing.core._ object Test { def main(args: Array[String]) = PApplet.main(Array[String]("Test")) } class Test extends PApplet { override def setup() = { } override def draw() = { } }

순열 만들기

Scala에서 순열을 만드는 2가지 방식을 생각해 볼 수 있겠습니다. 물론 더 여러가지가 있을 수 있겠지만... 1. 한번에 숫자 하나씩 처리하기 인자로 받은 리스트의 항목을 하나씩 가지고 결과물을 만들어 나가는 방법입니다. 매번 리스트 항목에서 하나를 선택해서 이미 만들어진 리스트의 앞, 중간, 뒤에 그 항목을 끼워넣습니다. List(1, 2, 3), List() -> List(2, 3), List(List(1)) -> List(3), List(List(2, 1), List(1, 2)) -> List(), List(List(3, 2, 1), List(2, 3, 1), List(2, 1, 3), List(3, 1, 2), List(1, 3, 2), List(1, 2, 3)) def permutation[A](xs:List[A]):List[List[A]] = { def mutate(x:A, ys:List[A]):List[List[A]] = { // ys의 앞, 중간, 뒤에 x를 끼워넣은 리스트를 반환 def helper(zs:List[A], prev:List[A], acc:List[List[A]]):List[List[A]] = zs match { case Nil => (ys :+ x)::acc case z::zs1 => helper(zs1, prev :+ z, (prev ++ (x::zs))::acc) } helper(ys, List(), List()) } def helper(ys:List[A], acc:List[List[A]]):List[List[A]] = ys match { case Nil => acc case y::ys1 => helper(ys1, acc.flatMap(mutate(y, _))) } helper(xs, List(Nil)) } ...