Elm vs HyperScript-Wordle 구현

19658 단어 hyperscriptwebdevelm

HyperScript: Demo, The source code is in the HTML Page Source.

Elm: Demo, Source Code, Playground


며칠 전에 HyperScript에서 간단한Wordle 실현을 만났는데 이것은 이벤트를 위한 새로운 전방 스크립트 언어로 영감HyperTalkhtmx의 동반자로부터 왔다.
htmx의 반려자가 여기서 도대체 무엇을 대표하는지 확실하지 않다.둘 다 same company에 의해 시작되었거나 같은 페이지에서 서로 보완되었을 수도 있으며, 공통된 목표는 자바스크립트를 사용하지 않는 것이다.
Wordle의 HyperScript 구현은 를 사용합니다.
코드는 HTML 페이지의 소스 코드에 위치하고 전체 구현이 이렇게 치밀하여 매우 인상적이다.
그래서 나는 Elm에서 그것을 다시 쓰기로 결정했다. 어떻게 비교하는지 보자.


DOM은 나라입니다.
HyperScript 버전은 DOM 주위에 구축됩니다.DOM은 응용 프로그램 상태를 저장하는 전역 변수로 사용되며 JQuery를 사용하여 웹 응용 프로그램을 작성하는 방식과 유사합니다.
구체적으로 말하면 세 가지 종류.bg-muted, .bg-warning.bg-success가 응용 프로그램의 전체 생명 주기에 기록되고 읽혀져 게임판과 키보드의 블록 상태를 변경한다.
사용자가 입력한 최신 줄을 표시하는 클래스.guess도 있습니다.
HyperScript 부분은 <script> 요소에 쓰이고 부분은 HTML에 연결되며 _ 속성을 사용합니다.
<script type="text/hyperscript">
    init fetch words.json as json then set $word to (random in it).toUpperCase() then log $word

    def submit()
        set remaining to $word
        repeat for ch in children of first .guess index i
            set key to <[letter=${ch.innerText}]/>
            add .bg-muted to key
            if ch.innerText == $word[i] then
                add .bg-success to ch add .bg-success to key
                set remaining to remaining.replace(ch.innerText, '')
            end
        end
        repeat for ch in children of first .guess
            set key to <[letter=${ch.innerText}]/>
            if remaining.includes(ch.innerText) then add .bg-warning to ch add .bg-warning to key end
            set remaining to remaining.replace(ch.innerText, '')
        end
        if (.bg-success in first .guess).length == 5 then remove .guess from .guess
        otherwise remove .guess from first .guess
    end

    behavior kbdRow(keys) 
        on click[target[@letter]] send keyup(keyCode: (target[@letter]).charCodeAt(0)) to <body/>
        init repeat for ch in keys 
            append `<button letter='${ch}' class='secondary ma1 pa2 w2'>${ch}</button>` to me
    end
</script>

<body _="
    on keyup(keyCode)[keyCode >= 65 and keyCode <= 90] put String.fromCharCode(keyCode) into first <:empty/> in first .guess
    on keyup(keyCode)[keyCode == 8] put '' into last <.guess > :not(:empty)/>
    on keyup(keyCode)[keyCode == 13 and (<:not(:empty)/> in first .guess).length == 5] call submit()
    ">
    <div class="container">
        <h1 class="tc">Hyperwordle</h1>
        <div _="on load set h to my innerHTML then repeat 5 times put h at the end of me">
            <div class="guess contrast flex ttu tc b f3 w-100 justify-center">
                <span class="w3 h3 ma1 pa3 bg-muted"></span>
                <span class="w3 h3 ma1 pa3 bg-muted"></span>
                <span class="w3 h3 ma1 pa3 bg-muted"></span>
                <span class="w3 h3 ma1 pa3 bg-muted"></span>
                <span class="w3 h3 ma1 pa3 bg-muted"></span>
            </div>
        </div>
        <div class="flex justify-center ttu tc" _="install kbdRow(keys: 'QWERTYUIOP')"></div>
        <div class="flex justify-center ttu tc" _="install kbdRow(keys: 'ASDFGHJKL')"></div>
        <div class="flex justify-center ttu tc">
            <button class="secondary ma1 pa2 w-auto" _="on click send keyup(keyCode: 13) to <body/>">Enter</button>
            <div class="flex" _="install kbdRow(keys: 'ZXCVBNM')"></div>
            <button class="secondary ma1 pa2 w-auto" _="on click send keyup(keyCode: 8) to <body/>"></button>
        </div>
    </div>
</body>
Elm 버전은 The Elm Architecture을 사용하는데 그 중에서 응용 프로그램의 상태는 Model라는 불변 데이터 구조에 저장된다.페이지에는 함수가 HTML로 변환된 Model 표현만 표시됩니다.
이 실현에서 나는 이러한 생각을 채택했다. 만약에 일부 데이터가 다른 데이터에서 계산될 수 있다면 view에 저장해서는 안 된다는 것이다.이것은 통상적으로 매우 좋은 방법이다. 왜냐하면 모델이 유행이 지난 계산을 포함하지 않도록 확보할 수 있기 때문이다.예를 들어 어떤 알파벳이 맞히거나 맞히지 못했는지, 그리고 게임이 끝나거나 게이머가 게임을 이겼는지에 대한 모든 개념은 필요할 때 제때에 계산된 것이다.
이것이 모델입니다.
type alias Model =
    { currentGuess : List Char
    , pastGuesses : List (List Char)
    , wordToGuess : List Char
    , error : Maybe String
    }
이것은 사용자가 입력한 내용과 추측할 비밀 단어, 그리고 추측할 단어 목록을 비동기적으로 불러올 때 발생할 수 있는 오류만 저장합니다.
Elm 버전 전체code입니다.이것은 그것의 Ellie 버전이다.

컴팩트
HyperScript의 치밀성은 여러 요소의 결합이지만 주로DOM을 향한 문법 사상이다.이 언어는 DOM과 깊이 융합되어 있다.클래스를 추가하거나 삭제하는 것은 매우 쉽다.예: Model.그것이 어떻게 이것보다 더 직접적이고 짧을 수 있습니까?
다른 행의 HyperScript 코드를 분석해 보겠습니다.
init fetch words.json as json then set $word to (random in it).toUpperCase() then log $word
이것은 훌륭한 작은 코드로 많은 일을 완성할 수 있다.
  • 프로그램이 초기화될 때 GET HTTP 요청을 보내서'words.json'
  • 을 가져옵니다.
  • JSON 데이터로 해석
  • JSON 목록(추측할 비밀 단어)에서 무작위 요소를 추출하여 on click toggle .red on me에 분배
  • 콘솔에 값 기록
  • Elm에서는 구조화된 작업이 더 필요합니다.
  • 함수에서 우리는 명령을 보내기 시작했다$word. Elm이 실행될 때 무작위 수를 원한다고 지시했다.이것은 순수 함수 코드이기 때문에 불순수 함수를 사용할 수 없습니다. 이것은 약간의 mindset-shift가 필요한 것 중의 하나입니다.엘름을 너의 조수로 삼아 너를 위해 일해라.그냥 물어봐.
  • 일단 무작위 수가 준비되면 우리는 소식을 받을 것이다.이 점에서 우리는 Elm이 운행할 때 GET에 GET 요청init을 보내도록 요구할 수 있다. 우리는 그것이 특정한 구조를 가지기를 바란다.
  • 일단 Random.generate NewRandom (Random.float 0 1) 데이터가 준비되면 우리는 모든 가능한 고장(네트워크 고장, JSON 파일이 아닌 것, 우리가 예상한 데이터 구조가 아닌 것)을 포함하는 또 다른 소식을 받을 것이다
  • .
  • 이 점에서 우리는 무작위 수와 단어 목록을 사용하여 어떤 비밀 단어를 최고치words.json에 저장할 수 있다.
  • 위에서 설명한 JSON 파일에 문제가 발생하면 HyperScript 버전은 어떻게 됩니까?
    이 프로그램은 계속 실행될 뿐이며, 첫 줄 문자를 입력할 수 있습니다.그 후, 그것은 일을 멈추었다.
    HyperScript 버전은 정상적으로 실행되는 동안에도 콘솔에서 오류가 발생합니다.예를 들어 한 줄의 다섯 글자에 도달한 후에 계속 입력하면 오류가 발생할 수 있다.해결 방안을 찾은 후 계속 입력할 때도 마찬가지다.코드를 줄이기 위해서 일부러 그런 것 같습니다.이러한 오류를 피하기 위해서는 약간의 추가 코드가 필요하다.
    반대로 Elm은 우리로 하여금 모든 가장자리 상황을 고려하게 하여 이러한 유형의 오류를 불가능하게 했다.따라서 GET 요청에 문제가 발생하면 화면에 메시지가 표시됩니다.

    타자 오류
    내 항목에서, 나는 모든 문자열을 한 번만 반복하려고 한다.문자열의 내용이 컴파일러의 검사를 거치지 않았기 때문에 입력 오류가 치명적일 수 있습니다.
    예를 들어 하나의 블록에는 세 가지 가능한 상태가 있는데 그것이 바로 words.json,Model,.bg-muted이다.DOM에 추가된 클래스는 다음과 같습니다.
  • .bg-warning(연회색 배경) 키보드의 키를 사용할 경우
  • .bg-success(연한 노란색 배경) 문자를 사용할 때 사용되지만 위치 오류
  • .bg-muted(녹색 배경) 캐릭터가 완전히 일치할 때
  • Elm에서 사용자 정의 유형으로 바꿉니다.
    type CharState
        = Muted
        | Warning
        | Success
    
    이것은 코드에 맞춤법 오류가 발생하지 않도록 보장한다.그런 다음 DOM에 클래스를 주입하는 변환 함수가 있습니다.
    charStateToClass : CharState -> String
    charStateToClass charState =
        case charState of
            Muted ->
                "bg-muted"
    
            Warning ->
                "bg-warning"
    
            Success ->
                "bg-success"
    
    이 문자열들은 전체 코드에만 나타나기 때문에 오류를 가져올 가능성은 최소화됩니다.
    HyperScript 코드는 다음과 같은 여러 문자열을 사용합니다.
    add .bg-success to ch add .bg-success to key
    
    문자열.bg-warning의 입력 오류는 감지되지 않으며 애플리케이션에 오류가 발생할 뿐 뚜렷한 오류 알림이 표시되지 않습니다.따라서 임시 테스트만 이런 문제점을 검출할 수 있다.

    코드 및 패키지 크기
    Elm은 최초의 HyperScript 구현을 모방하려고 시도했다. (더 실용적인 방식으로 Wordle 게임 자체를 실현할 수 있을 수도 있다.) 약 260줄의 코드가 있다.원래 HyperScript 버전의 약 5배입니다.
    나는 Elm 버전이 더욱 읽을 수 있고 확장하기 쉬우며 더 많은 기능을 가지고 있다고 생각한다. 그러나 여기서 나는 Elm에 대한 이해로 인해 우리는 편견이 있는 영역에 들어갔다.
    페이지 소스 코드의 내용을 제외하고 HyperScript 버전에는 86KB, 24KB 압축된 HyperScript 런타임 라이브러리가 필요합니다.
    Elm 언어는 컴파일된 JavaScript에 포함되어 있으므로 별도의 런타임 라이브러리가 필요하지 않습니다.Elm이 작성한Wordle로 이루어진 이 출력은 33KB, 14KB 축소되었다.
    이것은 로드할 컨텐트의 크기를 의미합니다. Elm은 HyperScript 크기의 절반 정도입니다.
    아직도 많은 차이점이 있지만 이것이 본문의 전체 내용이다.이것은 재미있는 연습이다.해당 코드를 보고 이 두 언어에 대한 더 많은 정보를 얻을 수 있습니다.
    Elmhere에는 Wordle의 대체 실현, 그리고.
    ❤️

    HyperScript: Demo, The source code is in the HTML Page Source.

    Elm: Demo, Source Code, Playground


    주: 과거에는 이 시리즈의 글에서'vs'를 제목으로 선택한 것에 대해 약간의 의견 차이가 있었다.나는 이런 비판에 동의한다. 있다.따라서'vs'는'죽음의 경기'가 아닌'비교'를 고려해 보세요.

    좋은 웹페이지 즐겨찾기