Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

코드의 한 쪽 끝에서 두 칸 이동할 경우의 동작에 대해서 #13

Open
xnuk opened this issue Jan 30, 2016 · 30 comments
Open

Comments

@xnuk
Copy link

xnuk commented Jan 30, 2016

* 커서가 코드 공간의 한 쪽 끝에 다다르면 커서는 반대편 끝으로 이동합니다.
  * 반대편 끝은 코드 텍스트에서 진행방향 반대편에 존재하는 첫 문자를 가리킵니다. 첫 문자는 줄바꿈 문자를 제외한 어떤 문자도 될 수 있습니다.

스펙에 서술된 부분입니다. 이 경우

우
유분
받망희
아유

이 코드는 4행 2열의 에 해당하는 "반대편 끝"은 을 가르켜서 2가 출력된다고 보는데, 의도한 부분이 맞나요?

@disjukr
Copy link
Member

disjukr commented Jan 30, 2016

두 칸 옮긴다의 해석이 커서를 두 칸씩 한 번 이동하느냐, 한 칸씩 두 번 이동하느냐,
반대편 끝의 해석이 코드 공간의 bounding rect에서 첫 칸(공백)인가, 해당 열에서 처음으로 공백이 아닌 칸()인가에 따라서 다르겠죠?

@xnuk
Copy link
Author

xnuk commented Jan 30, 2016

공백은 "문자" 취급을 받으니까, 문자가 없다고 표현하는 게 더 나을 거 같네요.

@disjukr
Copy link
Member

disjukr commented Jan 30, 2016

그렇다면 없음정도로 부르는 걸로..=3

@minacle
Copy link

minacle commented Jan 30, 2016

그렇다면 저 위치는 문자가 없는 칸일 뿐이지, 문자가 될 수는 없으니까 을 가리키는 구현이 올바른 게 되는 걸까요?

@minacle
Copy link

minacle commented Jan 30, 2016

또, @disjukr 님께서 말씀하셨듯, 한쪽 끝에 다다르면 반대쪽 끝으로 이동한다는 설명도 약간 모호한데,
여희멍번볃이라는 코드가 있다고 하면 가 한 칸씩 두 번 이동하는지, 두 칸을 한 번에 이동하는지에 따라 결과가 달라지게 돼요.
알파희가 사실상 표준으로 취급되고 있는 점을 생각한다면 두 칸을 한 번에 이동하는 게 맞겠지만, 이 부분도 확실히 해주면 좋겠어요.

@disjukr
Copy link
Member

disjukr commented Jan 30, 2016

지금은 스펙을 어떻게 해석하느냐에 따라 다른 구현이 나올 수 있으니 어떤것을 하나 집어서 "올바른" 구현이라고 부르긴 어렵겠죠.

제가 이해하기로 현재 대부분의 구현체는 두 칸씩 한 번 이동하며, 상하이동에 대해서는 bounding rect에서 첫 칸(없음)으로 이동하고, 좌우이동에 대해서는 처음으로 없음이 아닌 칸으로 이동하는 걸로 알고있어요.

개인적으로 상하이동과 좌우이동에서 반대쪽 끝의 해석은 일관성을 맞추는 것이 좋을 거라고 보고있구요. 구현의 용이성에 초점을 맞춘다면 bounding rect의 첫 칸으로 보내는 것이 좋겠고 사람의 직관에 초점을 맞춘다면 처음으로 없음이 아닌 칸으로 이동하는 것이 좋겠죠.

@minacle
Copy link

minacle commented Jan 30, 2016

사람의 직관에 초점을 맞춘다면 처음으로 없음이 아닌 칸으로 이동하는 것이 좋겠죠.

@xnuk 님께서 제시하신 코드

우
유분
받망희
아유

라면, 사람의 직관에 초점을 맞추어 으로 이동하게 되겠지요.

그런데 만약, 오른쪽에 주석이 있으면요?

우    -- 우—☆
유분   -- [명사] 죽은 사람의 뼈를 빻은 가루.
받망희  -- 왜 밯망히가 아니죠?
아유   -- 츠키미야 아유는 귀여워요!

사람의 직관에 초점을 맞춘다면 으로 가야 하겠지만, 저 경우에는 분명히  라는 공백 문자가 존재하기 때문에, 3이 출력되게 돼요.

@tirr-c
Copy link

tirr-c commented Jan 30, 2016

  • 주석을 정의하고
  • (#12와 함께) 공백 문자를 정의하고
  • 공백 문자와 주석을 무시하도록

하면 대부분의 모호함은 해결할 수 있을 것 같습니다. 근데 좀 복잡해지려나요...?

@minacle
Copy link

minacle commented Jan 30, 2016

개인적으로 주석을 따로 정의하는 것은 좋은 방향이 아니라고 생각합니다만 공백 문자를 무시하도록 하는 안은 찬성입니다. 유니코드에 존재하는 모든 공백 문자는 명시되어 있습니다.

@youknowone
Copy link
Member

조금 오해가 있는 것 같아서 첨부합니다.

알파희는 제가 만든 구현체인데, 일단 언어의 역사에 비해 구현체의 역사가 매우 짧아서 (10년 vs 1년 미만) 구현체로서 대표성을 가지기 어렵습니다. 가장 대표적인 구현체를 꼽으라면 최초의 구현체인 js 구현체가 가장 대표성을 띌 것이고, 이것을 제외하고도 그 이후에 나온 오랫동안 합법적인 구현체 가운데 하나로 인정받아 온 여러 구현체가 더 중요할 것입니다.
아희아희와의 관계는 조금 특수한데, 알파희는 아희아희의 개발에 필요한 기능 일부를 직접적으로 구현해 오면서 지원을 조금 했기 때문에, 아희아희가 알파희의 특수한 비표준 동작(표준에 어긋나지 않지만 명시되지도 않은 동작)에 의존하기 때문이고, 이 기능은 아희아희의 개발에 필요하지 않았으면 추가되지 않았을 기능입니다.

개인적으로는 다른 구현체 몇 개의 동작을 참고해서(일부러 참고하려고 고른건 아니고 그동안 써 본 것 위주로), 많은 구현체가 같은 동작을 하는 경우는 가급적 동일한 동작을 하도록 만들고, 구현이 서로 불일치하는 경우에는 제가 선호하는(제가 표준을 임의로 해석한) 동작을 따랐습니다. 따라서 알파희의 동작은 제 선호를 반영한 것이기 때문에 구현체간의 차이에서 특별히 대표성을 가진다고 말하기 더 어렵습니다.

@youknowone
Copy link
Member

공백에 관한 동작에는 표준 개정에는 조금 우려스러운 부분이 있습니다. 저는 이전의 구현체들의 동작과 일치하지 않는 동작에 따라 표준을 개정하는 것은 개정 이전의 구현체와 개정 이후의 구현체의 동작을 다르게 만들어서 구현체의 동작을 신뢰할 수 없게 만들거나, 반대로 개정된 표준을 무시하게 만들어서 표준의 가치를 떨어뜨리게 된다고 생각합니다.

현재 널리 알려진 구현체들 가운데 공백문자나 주석을 특별하게 취급하는 구현체는 하나도 없습니다. 사실 있다면 표준을 준수하지 않는 구현체들이겠지요. 이걸 "아희"의 이름으로 스펙으로 채택하는건 대단히 곤란한 일이라고 생각합니다.

@youknowone
Copy link
Member

아희 코드에 주석을 남기고 싶다면 현재의 상황에서 제가 권장하고 싶은 방법은 코드를 가급적 위-아래 경계를 넘을 때 2칸씩 이동하지 않도록 만들고, 코드 영역 밖의 아래쪽 등의 명백한 실행영역 밖에 주석을 남기는 것입니다. 코드가 위-아래 경계를 자주 넘나든다면 쉽지 않은 일일 수 있지요.

하지만 아희를 보통 난해한 프로그래밍 언어로 취급한다는 점을 고려하면 이정도의 난점은 괜찮다고 생각합니다. 난해한 프로그래밍언어들은 대개 한 가지의 목표에 집착하기 마련이고, 아희의 경우에는 이동 경로가 한글의 모음에 의존하는 것입니다. 따라서 아희의 아희의 특징을 오히려 무시하는 기능인 주석을 위해 복잡한 스펙을 추가하는건 (제 생각에는) 언어의 정체성에 반하는 일이 아닌가 생각됩니다.

@youknowone
Copy link
Member

본래 이슈로 돌아가면, @xnuk 님이 질문하신 동작은 현재 아희 스펙으로는 명확히 설명되지 않는 부분입니다. "반대쪽 끝"에 대한 정의가 제대로 되어 있지 않거든요. 제가 선호하는 해석은 "이동을 처리한 후 코드 경계를 넘어가면 반드시 반대편의 문자가 있는 첫 칸으로 도달한다" 입니다. 하지만 구현체 중에는 1칸씩 두번 이동하는 것처럼 간주해서 2칸 이동 중 첫번째에 반대편 끝으로 넘어가고 한번 더 이동하는 경우()도 있습니다. 둘다 표준과 딱히 부합하지 않는다고 말하기 어려운 동작이죠. 심지어는 빈 칸을 실제로는 존재하는 빈 문자가 가득 찬 영역으로 여기고 첫 이동에는 위의 공간에, 두번째 이동에는 에 도달하는 경우도 있고, 저는 이 경우도 현재의 스펙에는 일치하는 동작이라고 생각합니다.

@youknowone
Copy link
Member

아희 org에는 snippets라는 저장소가 있는데요. 여기에는 표준에서 불명확한 동작만을 모아놓은 디렉토리(undefined)가 있습니다.
다른 불명확한 표준에 관심이 있으면 이 디렉토리의 다른 파일을 좀 더 찾아보셔도 좋을 것 같습니다.
이 동작에 관련된 파일 링크도 같이 남길게요.

https://github.com/aheui/snippets/blob/master/undefined/boundary.aheui

@disjukr
Copy link
Member

disjukr commented Jan 30, 2016

일단 주석이 아희에 어울리지 않는다는 의견에는 공감하지만 반대쪽 끝으로 이동 시에 공백문자를 특별하게 취급하는 것을 스펙으로 채택하는 것은 저는 문제되지 않는 부분이라고 생각합니다.
저는 '처음으로 나오는 공백이 아닌 문자'를 반대쪽 끝으로 정의하는 것이 합리적이라고 생각합니다.

기존에 아희 스펙으로 명확하게 정의되지 않은 동작에 의존하는 코드가 있다면 그 것은 스펙이 명확해지기 전까지는 아희 방언으로 작성된 코드라고 봐야 한다고 생각합니다. 그런 코드들은 모든 기존 스펙을 준수하는 아희 구현체에서 동일하게 돌아간다는 보장을 할 수가 없을 테니까요.

스펙에서 정의를 명확하게 만든 다음 기존 구현체들을 그에 맞도록 개선하는 쪽이 옳다고 생각합니다.

@minacle
Copy link

minacle commented Jan 30, 2016

사실 아희 콰인은 가희1판 구현체에서 정상적으로 실행되었어야 합니다. 하지만 ㅑㅕㅛㅠ 계열 이동을 한 칸씩 두 번 이동으로 정의해서 무한 루프를 돌았기 때문에 아희 콰인이 정상적으로 실행되지 않았지요. (가장 긴 줄 끝에 점 하나를 찍으니 제대로 작동하고 종료되었습니다.) 그리고 아희 콰인은 미정의 디렉토리에 들어있지 않습니다. 이것은 두 칸씩 한 번 이동을 사실상 표준으로 삼고 있다는 이야기가 되고, 우연히도 아무도 눈치채지 못하고 있을 뿐이었다는 이야기가 됩니다.

@minacle
Copy link

minacle commented Jan 30, 2016

그리고, 이제는 이동 규칙을 명확히 할 때가 왔다고 생각합니다. 말씀하신대로, 아희는 오래된 언어입니다. 그럼에도 표준을 완벽하게 따르는 구현체는 아직 존재하지 않습니다. 이것은 아희의 발전에 걸림돌이 되고 있다고 저는 생각합니다. 모든 구현체가 미묘하게 다르게 동작합니다. 그 어떤 코드도 모든 환경에서 똑같이 작동하지 않습니다. 이것은 사실 말이 안 되는 일이기도 합니다.

@minacle
Copy link

minacle commented Jan 30, 2016

물론 표준을 갑자기 하루아침에 바꾸는 것은 어려울테니, 이제부터라도 충분한 논의를 통해 어느 한 쪽으로 못박아두는 것이 좋다고 생각합니다. 그리고, 모호한 부분은 이동 규칙 뿐만이 아니니까요.

@youknowone
Copy link
Member

미정의 디렉토리는 이해하기 쉬운 간단한 코드만 포함하기 때문에 그렇습니다. 콰인은 단지 모든 구현체를 커버하지 않는 코드일 뿐인거죠. 두 칸씩 한번 이동을 사실상 표준으로 삼고 있다는 얘기는 사실과 다릅니다.

두번째 얘기도 정확히 얘기하자면 표준을 완벽하게 따르는 구현체는 많이 있습니다. 여전히 그 구현체들 간의 동작이 일치하지 않을 뿐이지요. 만일 처음 말씀하신대로 두 칸씩 한번 이동이 사실상의 표준이었다면 이걸 표준으로 명시하는데는 큰 문제가 없다고 생각합니다. 하지만 지금은 그 부분이 구현이 일치하지 않는 대표적 사례이기 때문에 이전의 구현을 무시하고 일방적으로 고치기에는 무리가 있고, 과거 표준과의 호환을 포기하는 새 아희 표준의 버전을 만들어서만 달성 가능한 목표라고 생각합니다.

보다 엄밀한 동작과 기능 확장 모두를 포함하여 제안했던 아희2015의 이슈 링크입니다.
#8

이 중 엄밀한 동작에 관한 제안의 일부는 현재에도 사실상 표준인 것으로 판단하여 포함되었고, 일부는 논란의 여지가 있다고 생각해서 빠졌습니다. 이 패치는 아래링크에서 확인하실 수 있습니다.
#11

개인적으로는 사실상 표준에 해당하던 많은 기능이 지난번 개정에 실제 표준으로 포함되어서 이제 사실상 표준인데 표준에 반영이 안되고 남은 부분은 상당히 적다고 생각합니다.

@minacle
Copy link

minacle commented Jan 30, 2016

따라서 콰인은 실행이 돼도 안돼도 딱히 상관 없다는 거군요. 조금 안타까운 이야기지만..

아희2015는 확실히 흥미롭네요. 만일 저게 실제로 자리매김하게 된다면 아희는 현상유지한 채로 아희와 비슷하게 생긴 별개의 언어처럼 취급되는 건가요? (예를 들어 파이썬2와 3의 관계처럼)

@youknowone
Copy link
Member

비슷하게 보이기도 하고 호환되는 코드도 만들수 있지만 기본적으로는 양쪽이 서로 호환성을 갖지 않는다는 점에서 비슷한 관계겠네요.

@youknowone
Copy link
Member

@disjukr 공백 문제에 관해서는 대부분의 구현체가 공백도 하나의 무시할 문자로 취급합니다. 현재의 표준을 엄밀히 해석하면 공백은 "유니코드 hangul syllable area 영역 밖의 문자" 이외의 어떤 다른 해석도 불가능합니다. 물론 표준 자체에 버그가 있어서 작성할 때의 의도와 설명이 일치하지 않을 수 있는데, 이게 널리 받아들여지지 않는 해석인지 아닌지는 그간 나온 구현체들의 동작을 보면 되겠죠. 그런데 대부분의 구현체는 공백을 특수하게 다루지 않고 있으므로 공백을 한글이 아닌 글자 한 자로 취급하는 것은 별 이견 없는 표준 해석인걸로 볼 수 있겠습니다. 따라서 스펙도 명확하고 다른 구현체의 동작도 명확하다고 보는게 다수의 사람에게 더 합리적인 결정이라고 보는게 타당합니다. (이동 규칙에 따라 공백이 문자이냐 아니냐는 별로 중요한 일이 아닐 수 있지만, 이런 경우에는 역시 공백을 별도로 처리하지 않겠지요)

설사 표준이 모호하더라도(공백의 경우는 아니지만), 기존의 구현체들이 일관성 있는 방향으로 구현되어 있다면 기존의 구현체에서 사실상의 표준으로 받아들여져 존중해 오던 구현과 다른 구현을 강요하기 위해 표준의 권위를 이용하려 드는 것보다는 표준을 현실구현에 맞추어 혼란을 줄이는 방향으로 개정하는 것이 바람직할 것입니다.

@puzzlet
Copy link
Member

puzzlet commented Feb 3, 2016

장황해졌으니 정리해 보겠습니다. ㅑㅕㅛㅠ는 대부분 '두 칸씩 한 번 이동'으로 해석합니다. '한 칸씩 두 번 이동'으로 해석하는 구현체는 거의 없으니 논의하지 않겠습니다. 한편 '반대쪽 끝'에 대한 해석은 구현별로 크게 2종류로 나뉘는 것 같습니다.

  • (ㄱ) bounding rect의 끝을 '반대쪽 끝'으로 해석
  • (ㄴ) 왼쪽/오른쪽 끝은 각 줄의 끝, 위/아래 끝은 bounding rect의 끝을 '반대쪽 끝'으로 해석

그리고 여기에서 새로 나온 이야기로 다음이 있습니다.

  • (ㄷ) 가로줄이든 세로줄이든 공백을 제외한 문자가 시작되는 곳을 '반대쪽 끝'으로 해석
  • (ㄸ) 가로줄이든 세로줄이든 어떤 문자라도 시작되는 곳을 '반대쪽 끝'으로 해석

제가 아희로 코드를 짜본 경험으로 (ㄱ)은 불편하고 직관적이지 않았습니다. (ㄴ)은 코딩하기는 편하지만 엄밀히 따져보면 뭔가 일관성이 없죠. 가로와 세로를 바꿔버리면 다른 동작을 하는 코드를 만들 수 있습니다. (ㄷ)은 (ㄱ)과 (ㄴ)의 문제가 없지만 대신 다음 문제가 있습니다.

  1. 지금까지 공백 문자를 '채우는 문자'(예: ※)처럼 써왔는데, 그 의미가 달라져버려도 괜찮은가?
  2. 공백 문자를 어디까지 허용해야 할 것인가? 예를 들어 no-break space를 공백 문자로 볼 것인가?
  3. 아직 어떤 구현체에서도 (ㄷ)을 쓰지 않았는데, (ㄷ)을 표준으로 정해버려도 괜찮은가?

프로그래밍 언어는 사람들이 많이 써야 발전할 수 있고 이건 아희도 예외가 아니라고 생각합니다. 다른 분들이 코딩하는 모습을 많이 본 적은 없지만, 어떤 줄의 길이가 늘어나서 다른 줄의 실행에 영향이 생기는 건 혼란스러운 상황이므로 저는 일단 (ㄱ)만큼은 지지할 수 없습니다.

만약 2005년에 이 문제를 알았더라면 저는 (ㄷ)이나 (ㄸ)으로 정해버렸을 것 같습니다. 하지만 지금은 어느 쪽으로 정해지더라도 불만이 남고 혼란이 생길 것 같네요. 10년 전에는 상상할 수 없었던 아희의 레거시가 생겨버린 거죠.

P. S. 만약 콰인이 안 돌아가게 된다면, 콰인은 제가 고치면 됩니다

P. P. S.

코드 예:

예
예 예예
 예예 예
 예 예

(ㄱ)의 '맨 끝'

위/아래    왼쪽/오른쪽
-----   |   |
        |   |
        |   |
-----   |   |

(ㄴ)의 '맨 끝':

위/아래    왼쪽/오른쪽
-----   |
        |  |
        |   |
-----   |  |

(ㄷ)의 '맨 끝'

위/아래    왼쪽/오른쪽
-       |
- --    |  |
 -- -    |  |
 - -     | |

(ㄸ)의 '맨 끝'

위/아래    왼쪽/오른쪽
-       |
 ---    |  |
    -   |   |
----    |  |

@youknowone
Copy link
Member

(ㄷ) 에 대해서는 공백이 호환 문제를 일으키는 원인이므로 현재 구현체들과 크게 엇나가지 않는 방법으로 정의하자면

  • 방향에 관계 없이 각 줄의 끝을 (실제로 문자가 처음 나타나는 위치를) '반대쪽 끝'으로 해석

할수 있겠지요.

우
우반망희
우받망희
우
아유

@Sait2000
Copy link

Sait2000 commented Feb 6, 2016

양 끝을 어디로 하느냐에 대한 논의만 이뤄지는 것 같은데 맨 끝에서 두칸 이동으로 끝을 넘었을때 도착하는 지점이 반대쪽 끝인지 그 다음 문자인지는 어떻게 되는건가요? 반대쪽 끝으로 이동하는 경우가 두 칸씩 한 번 이동, 반대쪽 끝 바로 다음으로 이동하는 경우를 한 칸씩 두 번 이동으로 부르고 있는 건가요?

@disjukr
Copy link
Member

disjukr commented Feb 6, 2016

스펙을 커서가 코드 공간의 한 쪽 끝에 다다르면 커서는 반대편 끝으로 이동합니다. 보다는 커서가 이동방향의 맨 끝을 벗어나면 커서는 벗어난 정도에 관계없이 이동방향과 크기를 유지한 채 반대쪽 끝으로 이동합니다.로 고치는게 좋을 것 같다는 생각이 드네요.
@Sait2000 님의 의견을 보고나니 한 쪽 끝에 다다르면이라는 표현은 한 쪽 끝을 얼마나 벗어났는지를 활용하겠다는 뜻으로 해석될 수 있을 것 같습니다.

@youknowone
Copy link
Member

@Sait2000 네 맞습니다. 그런데 퍼즐릿님 말에 의하면 그런 구현체는 거의 없는거 같네요. 위에 보면 가희라는 구현체는 한때 그랬던거같고요

@baehyunsol
Copy link

혹시 한번만 다시 정리를 부탁드려도 될까요?

우우우우우
우우우우우
우우우우우 헿
아아아아아아유

저 코드에서 를 밟은 다음에 어디로 가고, 어떤 속도를 유지해야 하나요? 제 구현체는 avis의 구현을 따라서 첫번째 행으로 가고, 속도는 2를 유지하도록 했습니다.

@xnuk
Copy link
Author

xnuk commented Feb 7, 2023

@baehyunsol 현재 스펙으로는 해당 동작에 대해서 명확히 설명되지 않고 있기에, "어떻게 해야 하나요?"에 대한 답은 드릴 수 없습니다. 다만, 를 밟았으므로 "속도"는 '아래로 두 칸'인 것이 명확해 보입니다.

#13 (comment) 퍼즐릿 님이 정리하신 것을 참고하면 이렇게 생각해볼 수 있겠습니다:

  • '두 칸씩 한 번 이동'의 경우:
    • (ㄱ), (ㄴ): 1행 7열의 빈칸으로 갑니다.
    • (ㄷ), (ㄸ): 3행 7열의 으로 갑니다.
  • '한 칸씩 두 번 이동'의 경우:
    • (ㄱ), (ㄴ): 2행 7열의 빈칸으로 갑니다.
    • (ㄷ), (ㄸ): 4행 7열의 로 갑니다.

@xnuk xnuk changed the title 스펙에 대해 질문이 있습니다. 코드의 한 쪽 끝에서 두 칸 이동할 경우의 동작에 대해서 Feb 7, 2023
@xnuk
Copy link
Author

xnuk commented Feb 7, 2023

알림이 온 김에 애매모호한 이슈 제목을 바꾸었습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants