Urbit
  • Introduction
  • Development

    • Getting Started
    • Environment Setup
    • Grants Program
    • Project Repositories
    • Precepts
    • System Overview

      • Arvo
      • Hoon
      • Nock
      • Vere
      • Azimuth
      • Cryptography
      • Arvo

        • Overview
        • Ames

          • Overview
          • Cryptography
          • API Reference
          • Scry Reference
          • Data Types
          • Behn

            • Overview
            • API Reference
            • Scry Reference
            • Examples
            • Clay

              • Overview
              • Architecture
              • Using Clay
              • Data Types
              • Scry Reference
              • API Reference
              • Examples
              • Marks

                • Overview
                • Writing Marks
                • Using Marks
                • Examples
              • Dill

                • Overview
                • API Reference
                • Scry Reference
                • Data Types
                • Eyre

                  • Overview
                  • External API Reference
                  • Internal API Reference
                  • Scry Reference
                  • Data Types
                  • Guide
                  • Ford

                    • Overview
                    • Gall

                      • Overview
                      • API Reference
                      • Data Types
                      • Iris

                        • Overview
                        • API Reference
                        • Data Types
                        • Example
                        • Jael

                          • Overview
                          • API Reference
                          • Scry Reference
                          • Data Types
                          • Examples
                          • Concepts

                            • Scries
                            • Subscriptions
                            • Tutorials

                              • Move Trace
                              • Reference

                                • Cryptography
                                • Filesystem Hierarchy
                              • Userspace

                                • Overview
                                • HTTP API Guide
                                • Gall Guide

                                  • Introduction
                                  • 1. Arvo
                                  • 2. The Agent Core
                                  • 3. Imports and Aliases
                                  • 4. Lifecycle
                                  • 5. Cards
                                  • 6. Pokes
                                  • 7. Structures and Marks
                                  • 8. Subscriptions
                                  • 9. Vanes
                                  • 10. Scries
                                  • 11. Failure
                                  • 12. Next Steps
                                  • Appendix: Types
                                  • Full-Stack Walkthrough

                                    • 1. Introduction
                                    • 2. Types
                                    • 3. Agent
                                    • 4. JSON
                                    • 5. Marks
                                    • 6. Eyre
                                    • 7. React app setup
                                    • 8. React app logic
                                    • 9. Desk and glob
                                    • 10. Summary
                                    • Graph Store

                                      • Graph Store Overview
                                      • Data Structure Overview
                                      • Validator Walkthrough
                                      • Sample Application: Library
                                      • Graph Store - Reference
                                      • Advanced Info
                                      • Threads

                                        • Overview
                                        • HTTP API
                                        • Reference
                                        • Basics

                                          • Fundamentals
                                          • Bind
                                          • Input
                                          • Output
                                          • Summary
                                          • Gall

                                            • Start Thread
                                            • Take Result
                                            • Take Facts
                                            • Stop Thread
                                            • Poke Thread
                                            • Examples

                                              • Fetch JSON
                                              • Child Thread
                                              • Main-loop
                                              • Poke Agent
                                              • Scry
                                              • Take Fact
                                            • Distribution

                                              • Overview
                                              • Guide
                                              • Docket File
                                              • Glob
                                              • Dojo Tools
                                            • Hoon

                                              • Overview
                                              • Hoon School

                                                • 1.1 Introduction
                                                • 1.1.1 Walkthrough: List of Numbers
                                                • 1.2 Nouns
                                                • 1.3 Hoon Syntax
                                                • 1.3.1 Walkthrough: Conditionals
                                                • 1.4 Gates (Hoon Functions)
                                                • 1.4.1 Walkthrough: Recursion
                                                • 1.5 Lists
                                                • 1.5.1 Walkthrough: Fibonacci Sequence
                                                • 1.6 The Subject and Its Legs
                                                • 1.6.1 Walkthrough: Ackermann Function
                                                • 1.7 Arms and Cores
                                                • 1.7.1 Walkthrough: Caesar Cipher
                                                • 1.8 Doors
                                                • 1.8.1 Bank Account
                                                • 1.9 Generators
                                                • 2.1 Atoms, Auras, and Simple Cell Types
                                                • 2.2 Type Checking and Type Inference
                                                • 2.3 Structures and Complex Types
                                                • 2.3.1 Walkthrough: Libraries
                                                • 2.3.2 Molds
                                                • 2.4 Standard Library: Trees, Sets, and Maps
                                                • 2.5 Type Polymorphism
                                                • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                                • 2.5.2 Walkthrough: Lead Polymorphism
                                                • 2.6 Behn
                                                • 2.7 Gall
                                                • 2.7.1 Gall Walkthrough: Egg Timer
                                                • Guides

                                                  • CLI apps
                                                  • Parsing
                                                  • JSON
                                                  • Strings
                                                  • Sail (HTML)
                                                  • Writing Aqua Tests
                                                  • Reference

                                                    • Cheat Sheet
                                                    • Irregular forms
                                                    • Hoon Errors
                                                    • Hoon Style Guide
                                                    • Basic Types
                                                    • Advanced Types
                                                    • Auras
                                                    • Runes

                                                      • Atoms and strings
                                                      • Nock . ('dot')
                                                      • Wild ! ('zap')
                                                      • Change Subject = ('tis')
                                                      • Conditionals ? ('wut')
                                                      • Cores | ('bar')
                                                      • Arms + ('lus')
                                                      • Cells : ('col')
                                                      • Calls % ('cen')
                                                      • Casts ^ ('ket')
                                                      • Structures $ ('buc')
                                                      • Make ; ('mic')
                                                      • Hints ~ ('sig')
                                                      • Imports / ('fas')
                                                      • Terminators -- and ==
                                                      • Limbs and wings

                                                        • Limbs
                                                        • Wings
                                                        • Standard library

                                                          • Table of Contents
                                                          • 1a: Basic Arithmetic
                                                          • 1b: Tree Addressing
                                                          • 1c: Molds and Mold-Builders
                                                          • 2a: Unit Logic
                                                          • 2b: List Logic
                                                          • 2c: Bit Arithmetic
                                                          • 2d: Bit Logic
                                                          • 2e: Insecure Hashing
                                                          • 2f: Noun Ordering
                                                          • 2g: Unsigned Powers
                                                          • 2h: Set Logic
                                                          • 2i: Map Logic
                                                          • 2j: Jar and Jug Logic
                                                          • 2k: Queue Logic
                                                          • 2l: Container from Container
                                                          • 2m: Container from Noun
                                                          • 2n: Functional Hacks
                                                          • 2o: Normalizing Containers
                                                          • 2p: Serialization
                                                          • 2q: Molds and Mold-Builders
                                                          • 3a: Modular and Signed Ints
                                                          • 3b: Floating Point
                                                          • 3c: Urbit Time
                                                          • 3d: SHA Hash Family
                                                          • 3e: AES encryption (Removed)
                                                          • 3f: Scrambling
                                                          • 3g: Molds and Mold-Builders
                                                          • 4a: Exotic Bases
                                                          • 4b: Text Processing
                                                          • 4c: Tank Printer
                                                          • 4d: Parsing (Tracing)
                                                          • 4e: Parsing (Combinators)
                                                          • 4f: Parsing (Rule-Builders)
                                                          • 4g: Parsing (Outside Caller)
                                                          • 4h: Parsing (ASCII Glyphs)
                                                          • 4i: Parsing (Useful Idioms)
                                                          • 4j: Parsing (Bases and Base Digits)
                                                          • 4k: Atom Printing
                                                          • 4l: Atom Parsing
                                                          • 4m: Formatting Functions
                                                          • 4n: Virtualization
                                                          • 4o: Molds
                                                          • 5a: Compiler Utilities
                                                          • 5b: Macro Expansion
                                                          • 5c: Compiler Backend & Prettyprinter
                                                          • 5d: Parser
                                                          • 5e: Molds and mold builders
                                                          • 5f: Profiling support
                                                          • Zuse

                                                            • Table of Contents
                                                            • 2d(1-5): To JSON, Wains
                                                            • 2d(6): From JSON
                                                            • 2d(7): From JSON (unit)
                                                            • 2e(2-3): Print & Parse JSON
                                                        • Nock

                                                          • Nock Definition
                                                          • Explanation
                                                          • Example
                                                          • Implementations
                                                          • Vere

                                                            • C Runtime System
                                                            • Land of Nouns
                                                            • API overview by prefix
                                                            • C in Urbit
                                                            • Writing Jets
                                                            • Cryptography
                                                            • Azimuth

                                                              • Overview
                                                              • Urbit HD Wallet
                                                              • Azimuth Data Flow
                                                              • Azimuth.eth
                                                              • Ecliptic.eth
                                                              • Advanced Azimuth Tools
                                                              • Life and Rift
                                                              • Layer 2

                                                                • Layer 2 Overview
                                                                • Layer 2 Actions
                                                                • Transaction Format
                                                                • Rollers
                                                                • Roller HTTP RPC-API
                                                                • Custom Roller Tutorial
                                                              • Glossary

                                                                • Ames
                                                                • Aqua
                                                                • Arm
                                                                • Arvo
                                                                • Atom
                                                                • Azimuth
                                                                • Battery
                                                                • Behn
                                                                • Bridge
                                                                • Censures
                                                                • Ceremony
                                                                • chat
                                                                • Claims
                                                                • Clay
                                                                • Comet
                                                                • Core
                                                                • Delegated Sending
                                                                • Desk
                                                                • Dill
                                                                • Document Proposal
                                                                • Dojo
                                                                • Door
                                                                • Ecliptic
                                                                • Event Log
                                                                • Eyre
                                                                • Ford
                                                                • Galaxy
                                                                • Gall
                                                                • Gate
                                                                • HD Wallet
                                                                • Hoon
                                                                • Invite Tree
                                                                • Iris
                                                                • Jael
                                                                • Jaque
                                                                • Keyfile
                                                                • Landscape
                                                                • Mark
                                                                • Moon
                                                                • Nock
                                                                • Noun
                                                                • OTA Updates
                                                                • Payload
                                                                • pH
                                                                • Pier
                                                                • Pill
                                                                • Planet
                                                                • Proxies
                                                                • Replay
                                                                • Factory Reset
                                                                • Naive rollups
                                                                • Sail/Udon
                                                                • Senate
                                                                • Ship
                                                                • ship.arvo.network
                                                                • Star
                                                                • |sync
                                                                • Trap
                                                                • Upgrade Proposal
                                                                • Vane
                                                                • Vere
                                                                • Voting
                                                                • Wallet-Generator
                                                                Urbit
                                                                • Introduction
                                                                • Development

                                                                  • Getting Started
                                                                  • Environment Setup
                                                                  • Grants Program
                                                                  • Project Repositories
                                                                  • Precepts
                                                                  • System Overview

                                                                    • Arvo
                                                                    • Hoon
                                                                    • Nock
                                                                    • Vere
                                                                    • Azimuth
                                                                    • Cryptography
                                                                    • Arvo

                                                                      • Overview
                                                                      • Ames

                                                                        • Overview
                                                                        • Cryptography
                                                                        • API Reference
                                                                        • Scry Reference
                                                                        • Data Types
                                                                        • Behn

                                                                          • Overview
                                                                          • API Reference
                                                                          • Scry Reference
                                                                          • Examples
                                                                          • Clay

                                                                            • Overview
                                                                            • Architecture
                                                                            • Using Clay
                                                                            • Data Types
                                                                            • Scry Reference
                                                                            • API Reference
                                                                            • Examples
                                                                            • Marks

                                                                              • Overview
                                                                              • Writing Marks
                                                                              • Using Marks
                                                                              • Examples
                                                                            • Dill

                                                                              • Overview
                                                                              • API Reference
                                                                              • Scry Reference
                                                                              • Data Types
                                                                              • Eyre

                                                                                • Overview
                                                                                • External API Reference
                                                                                • Internal API Reference
                                                                                • Scry Reference
                                                                                • Data Types
                                                                                • Guide
                                                                                • Ford

                                                                                  • Overview
                                                                                  • Gall

                                                                                    • Overview
                                                                                    • API Reference
                                                                                    • Data Types
                                                                                    • Iris

                                                                                      • Overview
                                                                                      • API Reference
                                                                                      • Data Types
                                                                                      • Example
                                                                                      • Jael

                                                                                        • Overview
                                                                                        • API Reference
                                                                                        • Scry Reference
                                                                                        • Data Types
                                                                                        • Examples
                                                                                        • Concepts

                                                                                          • Scries
                                                                                          • Subscriptions
                                                                                          • Tutorials

                                                                                            • Move Trace
                                                                                            • Reference

                                                                                              • Cryptography
                                                                                              • Filesystem Hierarchy
                                                                                            • Userspace

                                                                                              • Overview
                                                                                              • HTTP API Guide
                                                                                              • Gall Guide

                                                                                                • Introduction
                                                                                                • 1. Arvo
                                                                                                • 2. The Agent Core
                                                                                                • 3. Imports and Aliases
                                                                                                • 4. Lifecycle
                                                                                                • 5. Cards
                                                                                                • 6. Pokes
                                                                                                • 7. Structures and Marks
                                                                                                • 8. Subscriptions
                                                                                                • 9. Vanes
                                                                                                • 10. Scries
                                                                                                • 11. Failure
                                                                                                • 12. Next Steps
                                                                                                • Appendix: Types
                                                                                                • Full-Stack Walkthrough

                                                                                                  • 1. Introduction
                                                                                                  • 2. Types
                                                                                                  • 3. Agent
                                                                                                  • 4. JSON
                                                                                                  • 5. Marks
                                                                                                  • 6. Eyre
                                                                                                  • 7. React app setup
                                                                                                  • 8. React app logic
                                                                                                  • 9. Desk and glob
                                                                                                  • 10. Summary
                                                                                                  • Graph Store

                                                                                                    • Graph Store Overview
                                                                                                    • Data Structure Overview
                                                                                                    • Validator Walkthrough
                                                                                                    • Sample Application: Library
                                                                                                    • Graph Store - Reference
                                                                                                    • Advanced Info
                                                                                                    • Threads

                                                                                                      • Overview
                                                                                                      • HTTP API
                                                                                                      • Reference
                                                                                                      • Basics

                                                                                                        • Fundamentals
                                                                                                        • Bind
                                                                                                        • Input
                                                                                                        • Output
                                                                                                        • Summary
                                                                                                        • Gall

                                                                                                          • Start Thread
                                                                                                          • Take Result
                                                                                                          • Take Facts
                                                                                                          • Stop Thread
                                                                                                          • Poke Thread
                                                                                                          • Examples

                                                                                                            • Fetch JSON
                                                                                                            • Child Thread
                                                                                                            • Main-loop
                                                                                                            • Poke Agent
                                                                                                            • Scry
                                                                                                            • Take Fact
                                                                                                          • Distribution

                                                                                                            • Overview
                                                                                                            • Guide
                                                                                                            • Docket File
                                                                                                            • Glob
                                                                                                            • Dojo Tools
                                                                                                          • Hoon

                                                                                                            • Overview
                                                                                                            • Hoon School

                                                                                                              • 1.1 Introduction
                                                                                                              • 1.1.1 Walkthrough: List of Numbers
                                                                                                              • 1.2 Nouns
                                                                                                              • 1.3 Hoon Syntax
                                                                                                              • 1.3.1 Walkthrough: Conditionals
                                                                                                              • 1.4 Gates (Hoon Functions)
                                                                                                              • 1.4.1 Walkthrough: Recursion
                                                                                                              • 1.5 Lists
                                                                                                              • 1.5.1 Walkthrough: Fibonacci Sequence
                                                                                                              • 1.6 The Subject and Its Legs
                                                                                                              • 1.6.1 Walkthrough: Ackermann Function
                                                                                                              • 1.7 Arms and Cores
                                                                                                              • 1.7.1 Walkthrough: Caesar Cipher
                                                                                                              • 1.8 Doors
                                                                                                              • 1.8.1 Bank Account
                                                                                                              • 1.9 Generators
                                                                                                              • 2.1 Atoms, Auras, and Simple Cell Types
                                                                                                              • 2.2 Type Checking and Type Inference
                                                                                                              • 2.3 Structures and Complex Types
                                                                                                              • 2.3.1 Walkthrough: Libraries
                                                                                                              • 2.3.2 Molds
                                                                                                              • 2.4 Standard Library: Trees, Sets, and Maps
                                                                                                              • 2.5 Type Polymorphism
                                                                                                              • 2.5.1 Walkthrough: Iron Polymorphism and Wet Polymorphism
                                                                                                              • 2.5.2 Walkthrough: Lead Polymorphism
                                                                                                              • 2.6 Behn
                                                                                                              • 2.7 Gall
                                                                                                              • 2.7.1 Gall Walkthrough: Egg Timer
                                                                                                              • Guides

                                                                                                                • CLI apps
                                                                                                                • Parsing
                                                                                                                • JSON
                                                                                                                • Strings
                                                                                                                • Sail (HTML)
                                                                                                                • Writing Aqua Tests
                                                                                                                • Reference

                                                                                                                  • Cheat Sheet
                                                                                                                  • Irregular forms
                                                                                                                  • Hoon Errors
                                                                                                                  • Hoon Style Guide
                                                                                                                  • Basic Types
                                                                                                                  • Advanced Types
                                                                                                                  • Auras
                                                                                                                  • Runes

                                                                                                                    • Atoms and strings
                                                                                                                    • Nock . ('dot')
                                                                                                                    • Wild ! ('zap')
                                                                                                                    • Change Subject = ('tis')
                                                                                                                    • Conditionals ? ('wut')
                                                                                                                    • Cores | ('bar')
                                                                                                                    • Arms + ('lus')
                                                                                                                    • Cells : ('col')
                                                                                                                    • Calls % ('cen')
                                                                                                                    • Casts ^ ('ket')
                                                                                                                    • Structures $ ('buc')
                                                                                                                    • Make ; ('mic')
                                                                                                                    • Hints ~ ('sig')
                                                                                                                    • Imports / ('fas')
                                                                                                                    • Terminators -- and ==
                                                                                                                    • Limbs and wings

                                                                                                                      • Limbs
                                                                                                                      • Wings
                                                                                                                      • Standard library

                                                                                                                        • Table of Contents
                                                                                                                        • 1a: Basic Arithmetic
                                                                                                                        • 1b: Tree Addressing
                                                                                                                        • 1c: Molds and Mold-Builders
                                                                                                                        • 2a: Unit Logic
                                                                                                                        • 2b: List Logic
                                                                                                                        • 2c: Bit Arithmetic
                                                                                                                        • 2d: Bit Logic
                                                                                                                        • 2e: Insecure Hashing
                                                                                                                        • 2f: Noun Ordering
                                                                                                                        • 2g: Unsigned Powers
                                                                                                                        • 2h: Set Logic
                                                                                                                        • 2i: Map Logic
                                                                                                                        • 2j: Jar and Jug Logic
                                                                                                                        • 2k: Queue Logic
                                                                                                                        • 2l: Container from Container
                                                                                                                        • 2m: Container from Noun
                                                                                                                        • 2n: Functional Hacks
                                                                                                                        • 2o: Normalizing Containers
                                                                                                                        • 2p: Serialization
                                                                                                                        • 2q: Molds and Mold-Builders
                                                                                                                        • 3a: Modular and Signed Ints
                                                                                                                        • 3b: Floating Point
                                                                                                                        • 3c: Urbit Time
                                                                                                                        • 3d: SHA Hash Family
                                                                                                                        • 3e: AES encryption (Removed)
                                                                                                                        • 3f: Scrambling
                                                                                                                        • 3g: Molds and Mold-Builders
                                                                                                                        • 4a: Exotic Bases
                                                                                                                        • 4b: Text Processing
                                                                                                                        • 4c: Tank Printer
                                                                                                                        • 4d: Parsing (Tracing)
                                                                                                                        • 4e: Parsing (Combinators)
                                                                                                                        • 4f: Parsing (Rule-Builders)
                                                                                                                        • 4g: Parsing (Outside Caller)
                                                                                                                        • 4h: Parsing (ASCII Glyphs)
                                                                                                                        • 4i: Parsing (Useful Idioms)
                                                                                                                        • 4j: Parsing (Bases and Base Digits)
                                                                                                                        • 4k: Atom Printing
                                                                                                                        • 4l: Atom Parsing
                                                                                                                        • 4m: Formatting Functions
                                                                                                                        • 4n: Virtualization
                                                                                                                        • 4o: Molds
                                                                                                                        • 5a: Compiler Utilities
                                                                                                                        • 5b: Macro Expansion
                                                                                                                        • 5c: Compiler Backend & Prettyprinter
                                                                                                                        • 5d: Parser
                                                                                                                        • 5e: Molds and mold builders
                                                                                                                        • 5f: Profiling support
                                                                                                                        • Zuse

                                                                                                                          • Table of Contents
                                                                                                                          • 2d(1-5): To JSON, Wains
                                                                                                                          • 2d(6): From JSON
                                                                                                                          • 2d(7): From JSON (unit)
                                                                                                                          • 2e(2-3): Print & Parse JSON
                                                                                                                      • Nock

                                                                                                                        • Nock Definition
                                                                                                                        • Explanation
                                                                                                                        • Example
                                                                                                                        • Implementations
                                                                                                                        • Vere

                                                                                                                          • C Runtime System
                                                                                                                          • Land of Nouns
                                                                                                                          • API overview by prefix
                                                                                                                          • C in Urbit
                                                                                                                          • Writing Jets
                                                                                                                          • Cryptography
                                                                                                                          • Azimuth

                                                                                                                            • Overview
                                                                                                                            • Urbit HD Wallet
                                                                                                                            • Azimuth Data Flow
                                                                                                                            • Azimuth.eth
                                                                                                                            • Ecliptic.eth
                                                                                                                            • Advanced Azimuth Tools
                                                                                                                            • Life and Rift
                                                                                                                            • Layer 2

                                                                                                                              • Layer 2 Overview
                                                                                                                              • Layer 2 Actions
                                                                                                                              • Transaction Format
                                                                                                                              • Rollers
                                                                                                                              • Roller HTTP RPC-API
                                                                                                                              • Custom Roller Tutorial
                                                                                                                            • Glossary

                                                                                                                              • Ames
                                                                                                                              • Aqua
                                                                                                                              • Arm
                                                                                                                              • Arvo
                                                                                                                              • Atom
                                                                                                                              • Azimuth
                                                                                                                              • Battery
                                                                                                                              • Behn
                                                                                                                              • Bridge
                                                                                                                              • Censures
                                                                                                                              • Ceremony
                                                                                                                              • chat
                                                                                                                              • Claims
                                                                                                                              • Clay
                                                                                                                              • Comet
                                                                                                                              • Core
                                                                                                                              • Delegated Sending
                                                                                                                              • Desk
                                                                                                                              • Dill
                                                                                                                              • Document Proposal
                                                                                                                              • Dojo
                                                                                                                              • Door
                                                                                                                              • Ecliptic
                                                                                                                              • Event Log
                                                                                                                              • Eyre
                                                                                                                              • Ford
                                                                                                                              • Galaxy
                                                                                                                              • Gall
                                                                                                                              • Gate
                                                                                                                              • HD Wallet
                                                                                                                              • Hoon
                                                                                                                              • Invite Tree
                                                                                                                              • Iris
                                                                                                                              • Jael
                                                                                                                              • Jaque
                                                                                                                              • Keyfile
                                                                                                                              • Landscape
                                                                                                                              • Mark
                                                                                                                              • Moon
                                                                                                                              • Nock
                                                                                                                              • Noun
                                                                                                                              • OTA Updates
                                                                                                                              • Payload
                                                                                                                              • pH
                                                                                                                              • Pier
                                                                                                                              • Pill
                                                                                                                              • Planet
                                                                                                                              • Proxies
                                                                                                                              • Replay
                                                                                                                              • Factory Reset
                                                                                                                              • Naive rollups
                                                                                                                              • Sail/Udon
                                                                                                                              • Senate
                                                                                                                              • Ship
                                                                                                                              • ship.arvo.network
                                                                                                                              • Star
                                                                                                                              • |sync
                                                                                                                              • Trap
                                                                                                                              • Upgrade Proposal
                                                                                                                              • Vane
                                                                                                                              • Vere
                                                                                                                              • Voting
                                                                                                                              • Wallet-Generator
                                                                                                                              Urbit/Documentation/Nock

                                                                                                                              Implementations

                                                                                                                              We use a C implementation for our Nock interpreter. But building a Nock interpreter in another language is a fun exercise. Check out our community Nock implementations, shown below our official C implementation. (Note: the community implementations were written for a slightly older version of Nock, Nock 5K. The current version is Nock 4K.):

                                                                                                                              Table of Contents

                                                                                                                              • C

                                                                                                                              • Clojure

                                                                                                                              • C#

                                                                                                                              • Groovy

                                                                                                                              • Haskell

                                                                                                                              • JavaScript

                                                                                                                              • Python

                                                                                                                              • Ruby

                                                                                                                              • Rust

                                                                                                                              • Scala

                                                                                                                              • Scheme

                                                                                                                              • Swift

                                                                                                                              C Implementation

                                                                                                                              The actual production Nock interpreter. Note gotos for tail-call elimination, and manual reference counting. More about the C environment can be found in the runtime system documentation.

                                                                                                                              /* _n_nock_on(): produce .*(bus fol).  Do not virtualize.
                                                                                                                              */
                                                                                                                              static u3_noun
                                                                                                                              _n_nock_on(u3_noun bus, u3_noun fol)
                                                                                                                              {
                                                                                                                                u3_noun hib, gal;
                                                                                                                              
                                                                                                                                while ( 1 ) {
                                                                                                                                  hib = u3h(fol);
                                                                                                                                  gal = u3t(fol);
                                                                                                                              
                                                                                                                              #ifdef U3_CPU_DEBUG
                                                                                                                                  u3R->pro.nox_d += 1;
                                                                                                                              #endif
                                                                                                                              
                                                                                                                                  if ( c3y == u3r_du(hib) ) {
                                                                                                                                    u3_noun poz, riv;
                                                                                                                              
                                                                                                                                    poz = _n_nock_on(u3k(bus), u3k(hib));
                                                                                                                                    riv = _n_nock_on(bus, u3k(gal));
                                                                                                                              
                                                                                                                                    u3a_lose(fol);
                                                                                                                                    return u3i_cell(poz, riv);
                                                                                                                                  }
                                                                                                                                  else switch ( hib ) {
                                                                                                                                    default: return u3m_bail(c3__exit);
                                                                                                                              
                                                                                                                                    case 0: {
                                                                                                                                      if ( c3n == u3r_ud(gal) ) {
                                                                                                                                        return u3m_bail(c3__exit);
                                                                                                                                      }
                                                                                                                                      else {
                                                                                                                                        u3_noun pro = u3k(u3at(gal, bus));
                                                                                                                              
                                                                                                                                        u3a_lose(bus); u3a_lose(fol);
                                                                                                                                        return pro;
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 1: {
                                                                                                                                      u3_noun pro = u3k(gal);
                                                                                                                              
                                                                                                                                      u3a_lose(bus); u3a_lose(fol);
                                                                                                                                      return pro;
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 2: {
                                                                                                                                      u3_noun nex = _n_nock_on(u3k(bus), u3k(u3t(gal)));
                                                                                                                                      u3_noun seb = _n_nock_on(bus, u3k(u3h(gal)));
                                                                                                                              
                                                                                                                                      u3a_lose(fol);
                                                                                                                                      bus = seb;
                                                                                                                                      fol = nex;
                                                                                                                                      continue;
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 3: {
                                                                                                                                      u3_noun gof, pro;
                                                                                                                              
                                                                                                                                      gof = _n_nock_on(bus, u3k(gal));
                                                                                                                                      pro = u3r_du(gof);
                                                                                                                              
                                                                                                                                      u3a_lose(gof); u3a_lose(fol);
                                                                                                                                      return pro;
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 4: {
                                                                                                                                      u3_noun gof, pro;
                                                                                                                              
                                                                                                                                      gof = _n_nock_on(bus, u3k(gal));
                                                                                                                                      pro = u3i_vint(gof);
                                                                                                                              
                                                                                                                                      u3a_lose(fol);
                                                                                                                                      return pro;
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 5: {
                                                                                                                                      u3_noun wim = _n_nock_on(bus, u3k(gal));
                                                                                                                                      u3_noun pro = u3r_sing(u3h(wim), u3t(wim));
                                                                                                                              
                                                                                                                                      u3a_lose(wim); u3a_lose(fol);
                                                                                                                                      return pro;
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 6: {
                                                                                                                                      u3_noun b_gal, c_gal, d_gal;
                                                                                                                              
                                                                                                                                      u3x_trel(gal, &b_gal, &c_gal, &d_gal);
                                                                                                                                      {
                                                                                                                                        u3_noun tys = _n_nock_on(u3k(bus), u3k(b_gal));
                                                                                                                                        u3_noun nex;
                                                                                                                              
                                                                                                                                        if ( 0 == tys ) {
                                                                                                                                          nex = u3k(c_gal);
                                                                                                                                        } else if ( 1 == tys ) {
                                                                                                                                          nex = u3k(d_gal);
                                                                                                                                        } else return u3m_bail(c3__exit);
                                                                                                                              
                                                                                                                                        u3a_lose(fol);
                                                                                                                                        fol = nex;
                                                                                                                                        continue;
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 7: {
                                                                                                                                      u3_noun b_gal, c_gal;
                                                                                                                              
                                                                                                                                      u3x_cell(gal, &b_gal, &c_gal);
                                                                                                                                      {
                                                                                                                                        u3_noun bod = _n_nock_on(bus, u3k(b_gal));
                                                                                                                                        u3_noun nex = u3k(c_gal);
                                                                                                                              
                                                                                                                                        u3a_lose(fol);
                                                                                                                                        bus = bod;
                                                                                                                                        fol = nex;
                                                                                                                                        continue;
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 8: {
                                                                                                                                      u3_noun b_gal, c_gal;
                                                                                                                              
                                                                                                                                      u3x_cell(gal, &b_gal, &c_gal);
                                                                                                                                      {
                                                                                                                                        u3_noun heb = _n_nock_on(u3k(bus), u3k(b_gal));
                                                                                                                                        u3_noun bod = u3nc(heb, bus);
                                                                                                                                        u3_noun nex = u3k(c_gal);
                                                                                                                              
                                                                                                                                        u3a_lose(fol);
                                                                                                                                        bus = bod;
                                                                                                                                        fol = nex;
                                                                                                                                        continue;
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 9: {
                                                                                                                                      u3_noun b_gal, c_gal;
                                                                                                                              
                                                                                                                                      u3x_cell(gal, &b_gal, &c_gal);
                                                                                                                                      {
                                                                                                                                        u3_noun seb = _n_nock_on(bus, u3k(c_gal));
                                                                                                                                        u3_noun pro;
                                                                                                                              
                                                                                                                                        u3t_off(noc_o);
                                                                                                                                        pro = u3j_kick(seb, b_gal);
                                                                                                                                        u3t_on(noc_o);
                                                                                                                              
                                                                                                                                        if ( u3_none != pro ) {
                                                                                                                                          u3a_lose(fol);
                                                                                                                                          return pro;
                                                                                                                                        }
                                                                                                                                        else {
                                                                                                                                          if ( c3n == u3r_ud(b_gal) ) {
                                                                                                                                            return u3m_bail(c3__exit);
                                                                                                                                          }
                                                                                                                                          else {
                                                                                                                                            u3_noun nex = u3k(u3at(b_gal, seb));
                                                                                                                              
                                                                                                                                            u3a_lose(fol);
                                                                                                                                            bus = seb;
                                                                                                                                            fol = nex;
                                                                                                                                            continue;
                                                                                                                                          }
                                                                                                                                        }
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                              
                                                                                                                                    case 10: {
                                                                                                                                      u3_noun p_gal, q_gal;
                                                                                                                              
                                                                                                                                      u3x_cell(gal, &p_gal, &q_gal);
                                                                                                                                      {
                                                                                                                                        u3_noun zep, hod, nex;
                                                                                                                              
                                                                                                                                        if ( c3y == u3r_du(p_gal) ) {
                                                                                                                                          u3_noun b_gal = u3h(p_gal);
                                                                                                                                          u3_noun c_gal = u3t(p_gal);
                                                                                                                                          u3_noun d_gal = q_gal;
                                                                                                                              
                                                                                                                                          zep = u3k(b_gal);
                                                                                                                                          hod = _n_nock_on(u3k(bus), u3k(c_gal));
                                                                                                                                          nex = u3k(d_gal);
                                                                                                                                        }
                                                                                                                                        else {
                                                                                                                                          u3_noun b_gal = p_gal;
                                                                                                                                          u3_noun c_gal = q_gal;
                                                                                                                              
                                                                                                                                          zep = u3k(b_gal);
                                                                                                                                          hod = u3_nul;
                                                                                                                                          nex = u3k(c_gal);
                                                                                                                                        }
                                                                                                                              
                                                                                                                                        u3a_lose(fol);
                                                                                                                                        return _n_hint(zep, hod, bus, nex);
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                              
                                                                                                                                    case 11: {
                                                                                                                                      u3_noun ref = _n_nock_on(u3k(bus), u3k(u3h(gal)));
                                                                                                                                      u3_noun gof = _n_nock_on(bus, u3k(u3t(gal)));
                                                                                                                                      u3_noun val;
                                                                                                                              
                                                                                                                                      u3t_off(noc_o);
                                                                                                                                      val = u3m_soft_esc(ref, u3k(gof));
                                                                                                                                      u3t_on(noc_o);
                                                                                                                              
                                                                                                                                      if ( !_(u3du(val)) ) {
                                                                                                                                        u3m_bail(u3nt(1, gof, 0));
                                                                                                                                      }
                                                                                                                                      if ( !_(u3du(u3t(val))) ) {
                                                                                                                                        //
                                                                                                                                        //  replace with proper error stack push
                                                                                                                                        //
                                                                                                                                        u3t_push(u3nc(c3__hunk, _n_mush(gof)));
                                                                                                                                        return u3m_bail(c3__exit);
                                                                                                                                      }
                                                                                                                                      else {
                                                                                                                                        u3_noun pro;
                                                                                                                              
                                                                                                                                        u3z(gof);
                                                                                                                                        u3z(fol);
                                                                                                                                        pro = u3k(u3t(u3t(val)));
                                                                                                                                        u3z(val);
                                                                                                                              
                                                                                                                                        return pro;
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    c3_assert(!"not reached");
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              }

                                                                                                                              Clojure

                                                                                                                              From Matt Earnshaw:

                                                                                                                              (ns anock.core
                                                                                                                                (:import anock.NockException))
                                                                                                                              
                                                                                                                              (declare atom? cell? cell)
                                                                                                                              
                                                                                                                              (defn noun?
                                                                                                                                "A noun is an atom or a cell."
                                                                                                                                [noun & ns]
                                                                                                                                (if ns false
                                                                                                                                    (or (atom? noun) (cell? noun))))
                                                                                                                              
                                                                                                                              (defn atom?
                                                                                                                                "An atom is a natural number."
                                                                                                                                [noun & ns]
                                                                                                                                (if ns false
                                                                                                                                 (and (integer? noun) (>= noun 0))))
                                                                                                                              
                                                                                                                              (defn cell?
                                                                                                                                "A cell is an ordered pair of nouns."
                                                                                                                                [noun]
                                                                                                                                (cond
                                                                                                                                 (atom? noun) false
                                                                                                                                 (nil? noun) false
                                                                                                                                 (not= 2 (count noun)) false
                                                                                                                                 :else (and (noun? (first noun))
                                                                                                                                            (noun? (second noun)))))
                                                                                                                              
                                                                                                                              (defn tis
                                                                                                                                "= (pronounced 'tis') tests a cell for equality."
                                                                                                                                [noun]
                                                                                                                                (if (atom? noun) (throw (anock.NockException. "Cannot tis an atom."))
                                                                                                                                    (let [[a b] noun]
                                                                                                                                      (if (= a b) 0 1))))
                                                                                                                              
                                                                                                                              (defn wut
                                                                                                                                "? (pronounced 'wut') tests whether a noun is a cell."
                                                                                                                                [noun]
                                                                                                                                (cond
                                                                                                                                 (atom? noun) 1
                                                                                                                                 (cell? noun) 0
                                                                                                                                 :else (throw (anock.NockException. "Invalid noun."))))
                                                                                                                              
                                                                                                                              (defn lus
                                                                                                                                "+ (pronounced 'lus') adds 1 to an atom."
                                                                                                                                [noun]
                                                                                                                                (if (atom? noun) (inc noun)
                                                                                                                                    (throw (anock.NockException. "Can only lus atoms."))))
                                                                                                                              
                                                                                                                              (defn fas
                                                                                                                                "/ (pronounced 'fas') is a tree address function."
                                                                                                                                [noun]
                                                                                                                                (if (atom? noun) (throw (anock.NockException. "Cannot fas an atom."))
                                                                                                                                    (let [[a b] (cell noun)]
                                                                                                                                      (assert (and (pos? a) (atom? a)) "Subject of fas must be a positive atom.")
                                                                                                                                      (if (and (not (coll? b)) (or (= 2 a) (= 3 a)))
                                                                                                                                        (throw (anock.NockException. (str "Cannot fas noun: " noun))))
                                                                                                                                      (cond
                                                                                                                                        (= 1 a) b
                                                                                                                                        (= 2 a) (first b)
                                                                                                                                        (= 3 a) (second b)
                                                                                                                                        (even? a) (fas [2 (fas [(/ a 2) b])])
                                                                                                                                        (odd? a) (fas [3 (fas [(/ (dec a) 2) b])])))))
                                                                                                                              
                                                                                                                              (defn tar
                                                                                                                                "* (pronounced 'tar') means Nock"
                                                                                                                                [noun]
                                                                                                                                (if (atom? noun) (throw (anock.NockException. "Cannot tar an atom."))
                                                                                                                                    (try
                                                                                                                                      (let [noun (cell noun) [x [y z]] noun]
                                                                                                                                        (cond
                                                                                                                                          (cell? y) (cell (tar [x y]) (tar [x z]))
                                                                                                                                          (zero? y) (fas [z x])
                                                                                                                                          (= 1 y) z
                                                                                                                                          (= 3 y) (wut (tar [x z]))
                                                                                                                                          (= 4 y) (lus (tar [x z]))
                                                                                                                                          (= 5 y) (tis (tar [x z]))
                                                                                                                                          :else (let [[p q] z]
                                                                                                                                                  (cond
                                                                                                                                                    (= 2 y) (tar [(tar [x p]) (tar [x q])])
                                                                                                                                                    (= 6 y) (tar [x 2 [0 1] 2 [1 (first q) (second q)]
                                                                                                                                                                  [1 0] 2 [1 2 3] [1 0] 4 4 p])
                                                                                                                                                    (= 7 y) (tar [x 2 p 1 q])
                                                                                                                                                    (= 8 y) (tar [x 7 [[7 [0 1] p] 0 1] q])
                                                                                                                                                    (= 9 y) (tar [x 7 q 2 [0 1] 0 p])
                                                                                                                                                    (= 10 y) (if (cell? p)
                                                                                                                                                               (tar [x 8 (second p) 7 [0 3] q])
                                                                                                                                                               (tar [x q]))))))
                                                                                                                                      (catch RuntimeException e
                                                                                                                                        (throw (anock.NockException. (str "Cannot tar the noun " noun)))))))
                                                                                                                              
                                                                                                                              (def nock tar)
                                                                                                                              
                                                                                                                              ; Some convenience functions
                                                                                                                              (defn apply* [f x]
                                                                                                                                (if (and (= 1 (count x)) (coll? (first x)))
                                                                                                                                  (apply f x)
                                                                                                                                  (f x)))
                                                                                                                              
                                                                                                                              (defn bracket
                                                                                                                                "[a b c] -> [a [b c]]"
                                                                                                                                [[a & b :as c]]
                                                                                                                                (let [b (vec b)]
                                                                                                                                  (cond
                                                                                                                                    (and (noun? a) (apply noun? b)) (vec c)
                                                                                                                                    (apply noun? b) (apply vector (bracket a) b)
                                                                                                                                    (noun? a) [a (apply* bracket b)]
                                                                                                                                    :else [(bracket a) (apply* bracket b)])))
                                                                                                                              
                                                                                                                              (defn cell [& nouns]
                                                                                                                                (if (apply atom? nouns)
                                                                                                                                  (throw (anock.NockException. "Cannot convert atom to cell."))
                                                                                                                                  (apply* bracket nouns)))

                                                                                                                              C#

                                                                                                                              From Julien Beasley:

                                                                                                                              using System;
                                                                                                                              using System.Collections.Generic;
                                                                                                                              using System.Linq;
                                                                                                                              using System.Text;
                                                                                                                              using System.Text.RegularExpressions;
                                                                                                                              
                                                                                                                              namespace NockInterpreter
                                                                                                                              {
                                                                                                                                  class Interpreter
                                                                                                                                  {
                                                                                                                                      static Dictionary<string, Noun> memocache = new Dictionary<string, Noun>();
                                                                                                                              
                                                                                                                                      public static Noun Nock(Noun noun)
                                                                                                                                      {
                                                                                                                                      Start:
                                                                                                                                          Noun cache_noun;
                                                                                                                                          if (memocache.TryGetValue(noun.ToString(), out cache_noun))
                                                                                                                                          {
                                                                                                                                              return cache_noun;
                                                                                                                                          }
                                                                                                                              
                                                                                                                                          if (Atom.IsAtom(noun))
                                                                                                                                              throw new Exception("Infinite loop nocking an atom: " + noun.ToString());
                                                                                                                                          else
                                                                                                                                          {
                                                                                                                                              Noun subject = noun.n1;
                                                                                                                                              if (Noun.IsCell(noun.n2))
                                                                                                                                              {
                                                                                                                                                  Cell formula = (Cell)noun.n2;
                                                                                                                                                  if (Noun.IsAtom(formula.n1)) // we have lines 25-37 of spec
                                                                                                                                                  {
                                                                                                                                                      Atom op = (Atom)formula.n1;
                                                                                                                                                      Noun operands = formula.n2;
                                                                                                                              
                                                                                                                                                      switch (op.value)
                                                                                                                                                      {
                                                                                                                                                          case 0: // 25 ::    *[a 0 b]         /[b a]
                                                                                                                                                              memocache[noun.ToString()] = fas(operands, subject);
                                                                                                                                                              return memocache[noun.ToString()];
                                                                                                                                                          case 1: // 26 ::    *[a 1 b]         b
                                                                                                                                                              memocache[noun.ToString()] = operands;
                                                                                                                                                              return memocache[noun.ToString()];
                                                                                                                                                          case 2: // 27 ::    *[a 2 b c]       *[*[a b] *[a c]]
                                                                                                                                                              if (Noun.IsCell(operands))
                                                                                                                                                              {
                                                                                                                                                                  Noun a = Nock(subject, operands.n1);
                                                                                                                                                                  Noun b = Nock(subject, operands.n2);
                                                                                                                                                                  noun = Noun.CreateNoun(a, b);
                                                                                                                                                                  goto Start;
                                                                                                                                                                  //                                    return Nock(Nock(subject, operands.n1), Nock(subject, operands.n2));
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Atom after operand 2: " + operands.ToString());
                                                                                                                                                          case 3: // 28 ::    *[a 3 b]         ?*[a b]
                                                                                                                                                              memocache[noun.ToString()] = wut(Nock(subject, operands));
                                                                                                                                                              return memocache[noun.ToString()];
                                                                                                                                                          case 4: // 29 ::    *[a 4 b]         +*[a b]
                                                                                                                                                              memocache[noun.ToString()] = lus(Nock(subject, operands));
                                                                                                                                                              return memocache[noun.ToString()];
                                                                                                                                                          case 5: // 30 ::    *[a 5 b]         =*[a b]
                                                                                                                                                              memocache[noun.ToString()] = tis(Nock(subject, operands));
                                                                                                                                                              return memocache[noun.ToString()];
                                                                                                                                                          case 6: // 32 ::    *[a 6 b c d]     *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
                                                                                                                                                              if (Noun.IsCell(operands) && Noun.IsCell(operands.n2))
                                                                                                                                                              {
                                                                                                                                                                  Noun b = operands.n1;
                                                                                                                                                                  Noun c = operands.n2.n1;
                                                                                                                                                                  Noun d = operands.n2.n2;
                                                                                                                                                                  noun = Noun.CreateNoun("[" + subject + " 2 [0 1] 2 [1 " + c + " " + d + "] [1 0] 2 [1 2 3] [1 0] 4 4 " + b + "]");
                                                                                                                                                                  goto Start;
                                                                                                                                                                  //                                    return Nock(Noun.CreateNoun("[" + subject + " 2 [0 1] 2 [1 " + c + " " + d + "] [1 0] 2 [1 2 3] [1 0] 4 4 " + b + "]"));
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Unhandled pattern for operand 6");
                                                                                                                                                          case 7: // 33 ::    *[a 7 b c]       *[a 2 b 1 c]
                                                                                                                                                              if (Noun.IsCell(operands))
                                                                                                                                                              {
                                                                                                                                                                  Noun b = operands.n1;
                                                                                                                                                                  Noun c = operands.n2;
                                                                                                                                                                  noun = Noun.CreateNoun("[" + subject + " 2 " + b + " 1 " + c + "]");
                                                                                                                                                                  goto Start;
                                                                                                                                                                  //                                    return Nock(Noun.CreateNoun("[" + subject + " 2 " + b + " 1 " + c + "]"));
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Atom after operand 7: " + operands.ToString());
                                                                                                                                                          case 8: // 34 ::    *[a 8 b c]       *[a 7 [[7 [0 1] b] 0 1] c]
                                                                                                                                                              if (Noun.IsCell(operands))
                                                                                                                                                              {
                                                                                                                                                                  Noun b = operands.n1;
                                                                                                                                                                  Noun c = operands.n2;
                                                                                                                                                                  noun = Noun.CreateNoun("[" + subject + " 7 [[7 [0 1] " + b + "] 0 1] " + c + "]");
                                                                                                                                                                  goto Start;
                                                                                                                                                                  //                                    return Nock(Noun.CreateNoun("[" + subject + " 7 [[7 [0 1] " + b + "] 0 1] " + c + "]"));
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Atom after operand 8: " + operands.ToString());
                                                                                                                                                          case 9: // 35 ::    *[a 9 b c]       *[a 7 c 2 [0 1] 0 b]
                                                                                                                                                              if (Noun.IsCell(operands))
                                                                                                                                                              {
                                                                                                                                                                  Noun b = operands.n1;
                                                                                                                                                                  Noun c = operands.n2;
                                                                                                                                                                  noun = Noun.CreateNoun("[" + subject + " 7 " + c + " 2 [0 1] 0 " + b + "]");
                                                                                                                                                                  goto Start;
                                                                                                                                                                  //                                    return Nock(Noun.CreateNoun("[" + subject + " 7 " + c + " 2 [0 1] 0 " + b + "]"));
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Atom after operand 9: " + operands.ToString());
                                                                                                                                                          case 10:
                                                                                                                                                              if (Noun.IsCell(operands))
                                                                                                                                                              {
                                                                                                                                                                  if (Noun.IsCell(operands.n1)) // 36 ::    *[a 10 [b c] d]  *[a 8 c 7 [0 3] d]
                                                                                                                                                                  {
                                                                                                                                                                      Noun b = operands.n1.n1;
                                                                                                                                                                      Noun c = operands.n1.n2;
                                                                                                                                                                      Noun d = operands.n2;
                                                                                                                                                                      noun = Noun.CreateNoun("[" + subject + " 8 " + c + " 7 [0 3] " + d + "]");
                                                                                                                                                                      goto Start;
                                                                                                                                                                      //                                        return Nock(Noun.CreateNoun("[" + subject + " 8 " + c + " 7 [0 3] " + d + "]"));
                                                                                                                                                                  }
                                                                                                                                                                  else // 37 ::    *[a 10 b c]      *[a c]
                                                                                                                                                                  {
                                                                                                                                                                      Noun c = operands.n2;
                                                                                                                                                                      noun = Noun.CreateNoun(subject, c);
                                                                                                                                                                      goto Start;
                                                                                                                                                                      //                                        return Nock(subject, c);
                                                                                                                                                                  }
                                                                                                                                                              }
                                                                                                                                                              throw new Exception("Atom after operand 10: " + operands.ToString());
                                                                                                                                                          default:
                                                                                                                                                              throw new Exception("Unknown operand: " + op.value);
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  else // 23 ::    *[a [b c] d]     [*[a b c] *[a d]]
                                                                                                                                                  {
                                                                                                                                                      memocache[noun.ToString()] = Noun.CreateNoun(Nock(subject, formula.n1), Nock(subject, formula.n2));
                                                                                                                                                      return memocache[noun.ToString()];
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                                          throw new Exception("Unhandled pattern");
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun Nock(string program)
                                                                                                                                      {
                                                                                                                                          Noun noun = Noun.CreateNoun(program);
                                                                                                                                          return Nock(noun);
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun Nock(Noun n1, Noun n2)
                                                                                                                                      {
                                                                                                                                          Noun noun = Noun.CreateNoun(n1, n2);
                                                                                                                                          return Nock(noun);
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      private static Noun tis(Noun noun)
                                                                                                                                      {
                                                                                                                                          if (Noun.IsAtom(noun.ToString()))
                                                                                                                                              throw new Exception("Infinite loop tising an atom: " + noun.ToString());
                                                                                                                                          else
                                                                                                                                          {
                                                                                                                                              Cell cell = (Cell)noun;
                                                                                                                              
                                                                                                                                              if (cell.n1.ToString() == cell.n2.ToString())
                                                                                                                                                  return Noun.CreateNoun("0");
                                                                                                                                              else
                                                                                                                                                  return Noun.CreateNoun("1");
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      private static Noun lus(Noun noun)
                                                                                                                                      {
                                                                                                                                          if (Noun.IsAtom(noun.ToString()))
                                                                                                                                          {
                                                                                                                                              Atom a = (Atom)noun;
                                                                                                                                              int v = a.value + 1;
                                                                                                                                              return Noun.CreateNoun(v.ToString());
                                                                                                                                          }
                                                                                                                                          else
                                                                                                                                              throw new Exception("Infinite loop lusing a cell: " + noun.ToString());
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      private static Noun wut(Noun noun)
                                                                                                                                      {
                                                                                                                                          if (Noun.IsAtom(noun.ToString()))
                                                                                                                                              return Noun.CreateNoun("1");
                                                                                                                                          else
                                                                                                                                              return Noun.CreateNoun("0");
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      private static Noun fas(Noun n1, Noun n2)
                                                                                                                                      {
                                                                                                                                          Noun noun = Noun.CreateNoun(n1, n2);
                                                                                                                                          return fas(noun);
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      private static Noun fas(Noun noun)
                                                                                                                                      {
                                                                                                                                          if (Noun.IsAtom(noun.ToString()))
                                                                                                                                              throw new Exception("Infinite loop fasing an atom: " + noun.ToString());
                                                                                                                                          else
                                                                                                                                          {
                                                                                                                                              Cell c = (Cell)noun;
                                                                                                                                              // If n1 isn't an atom, I assume we throw? This isn't defined in the spec. Confirmed by John B by email. This spins forever.
                                                                                                                                              if (Noun.IsCell(c.n1.ToString()))
                                                                                                                                                  throw new Exception("Axis must be an atom: " + c.ToString());
                                                                                                                                              else
                                                                                                                                              {
                                                                                                                                                  Atom a = (Atom)c.n1;
                                                                                                                                                  if (a.value == 1)
                                                                                                                                                      return c.n2;
                                                                                                                                                  else if (a.value >= 2)
                                                                                                                                                  {
                                                                                                                                                      if (!Noun.IsCell(c.n2.ToString()))
                                                                                                                                                      {
                                                                                                                                                          throw new Exception("Only a cell can have an axis of 2 or 3: " + c.n2.ToString());
                                                                                                                                                      }
                                                                                                                                                      else
                                                                                                                                                      {
                                                                                                                                                          Cell c2 = (Cell)c.n2;
                                                                                                                                                          if (a.value == 2)
                                                                                                                                                              return c2.n1;
                                                                                                                                                          else if (a.value == 3)
                                                                                                                                                              return c2.n2;
                                                                                                                                                          else if (a.value % 2 == 0)
                                                                                                                                                          {
                                                                                                                                                              int half = a.value / 2;
                                                                                                                                                              return fas(Noun.CreateNoun("2", fas(Noun.CreateNoun(half.ToString(), c2))));
                                                                                                                                                          }
                                                                                                                                                          else if (a.value % 2 == 1)
                                                                                                                                                          {
                                                                                                                                                              int half = a.value / 2;
                                                                                                                                                              return fas(Noun.CreateNoun("3", fas(Noun.CreateNoun(half.ToString(), c2))));
                                                                                                                                                          }
                                                                                                                                                          else
                                                                                                                                                          {
                                                                                                                                                              throw new Exception("Infinite loop somewhere in fasing: " + c.n2.ToString());
                                                                                                                                                          }
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                              throw new Exception("Infinite loop somewhere in fasing: " + c.n2.ToString());
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  class Noun
                                                                                                                                  {
                                                                                                                                      public Noun n1;
                                                                                                                                      public Noun n2;
                                                                                                                              
                                                                                                                                      // takes a program, returns a pair of nouns, stringified.
                                                                                                                                      public static Tuple<string, string> SplitCell(string program)
                                                                                                                                      {
                                                                                                                              
                                                                                                                                          int stackCount = 0;
                                                                                                                                          int i = 0;
                                                                                                                                          // split the string right after the first space
                                                                                                                                          foreach (char c in program)
                                                                                                                                          {
                                                                                                                                              if (IsValidChar(c))
                                                                                                                                              {
                                                                                                                                                  if (c == '[')
                                                                                                                                                      stackCount++;
                                                                                                                                                  else if (c == ']')
                                                                                                                                                      stackCount--;
                                                                                                                                                  else if (c == ' ')
                                                                                                                                                  {
                                                                                                                                                      // if we see a space, and our stack count is at 1, then we've found our split point
                                                                                                                                                      if (stackCount == 1)
                                                                                                                                                      {
                                                                                                                                                          string a = program.Substring(1, i - 1);
                                                                                                                                                          string b = program.Substring(i + 1, program.Length - (i + 2));
                                                                                                                              
                                                                                                                                                          // to implement proper bracket closing, surround b with brackets if it isn't a cell and isn't an atom
                                                                                                                                                          if (!IsCell(b) && !IsAtom(b))
                                                                                                                                                              b = "[" + b + "]";
                                                                                                                                                          Tuple<string, string> tuple = new Tuple<string, string>(a, b);
                                                                                                                                                          return tuple;
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                              else
                                                                                                                                                  throw new Exception("Invalid char in cell: " + c);
                                                                                                                                              i++;
                                                                                                                                          }
                                                                                                                                          throw new Exception("Invalid cell: " + program);
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsCell(string program)
                                                                                                                                      {
                                                                                                                                          // check if cell is valid, as above but make sure no space after bracket
                                                                                                                                          // valid tokens are: space, int, [, ]
                                                                                                                                          // from [ => [, int
                                                                                                                                          // from int => space, ], int
                                                                                                                                          // from ] => space, ]
                                                                                                                                          // from space => int, [
                                                                                                                              
                                                                                                                                          // stack count must always be nonzero
                                                                                                                                          // first and last elements must be [ and ]
                                                                                                                              
                                                                                                                                          int i = 0; // i is the stack count for brackets.
                                                                                                                                          int counter = 0;
                                                                                                                                          char s = '\0'; // s is the last seen character
                                                                                                                                          // split the string right after the first space
                                                                                                                                          foreach (char c in program)
                                                                                                                                          {
                                                                                                                                              if (s == '\0')
                                                                                                                                              {
                                                                                                                                                  if (c != '[')
                                                                                                                                                      return false;
                                                                                                                                              }
                                                                                                                                              else if (s == '[')
                                                                                                                                              {
                                                                                                                                                  if (!(c == '[' || IsInt(c)))
                                                                                                                                                      return false;
                                                                                                                                              }
                                                                                                                                              else if (IsInt(s))
                                                                                                                                              {
                                                                                                                                                  if (!(IsInt(c) || c == ' ' || c == ']'))
                                                                                                                                                      return false;
                                                                                                                                              }
                                                                                                                                              else if (s == ']')
                                                                                                                                              {
                                                                                                                                                  if (!(c == ']' || c == ' '))
                                                                                                                                                      return false;
                                                                                                                                              }
                                                                                                                                              else if (s == ' ')
                                                                                                                                              {
                                                                                                                                                  if (!(c == '[' || IsInt(c)))
                                                                                                                                                      return false;
                                                                                                                                              }
                                                                                                                                              s = c;
                                                                                                                                              counter++;
                                                                                                                                              if (c == '[')
                                                                                                                                                  i++;
                                                                                                                                              else if (c == ']')
                                                                                                                                                  i--;
                                                                                                                                              if (i <= 0 && counter != program.Length) // stack count can't be zero unless it's the last character
                                                                                                                                                  return false;
                                                                                                                                          }
                                                                                                                              
                                                                                                                                          // We should end with stack count of zero
                                                                                                                                          if (i == 0)
                                                                                                                                              return true;
                                                                                                                                          else
                                                                                                                                              return false;
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsInt(char c)
                                                                                                                                      {
                                                                                                                                          if (c == '0' ||
                                                                                                                                              c == '1' ||
                                                                                                                                              c == '2' ||
                                                                                                                                              c == '3' ||
                                                                                                                                              c == '4' ||
                                                                                                                                              c == '5' ||
                                                                                                                                              c == '6' ||
                                                                                                                                              c == '7' ||
                                                                                                                                              c == '8' ||
                                                                                                                                              c == '9')
                                                                                                                                              return true;
                                                                                                                                          else
                                                                                                                                              return false;
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsValidChar(char c)
                                                                                                                                      {
                                                                                                                                          if (c == ' ' ||
                                                                                                                                              c == '[' ||
                                                                                                                                              c == ']' ||
                                                                                                                                              IsInt(c))
                                                                                                                                              return true;
                                                                                                                                          else
                                                                                                                                              return false;
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsAtom(string program)
                                                                                                                                      {
                                                                                                                                          int i = 0;
                                                                                                                                          if (int.TryParse(program, out i))
                                                                                                                                          {
                                                                                                                                              if (i >= 0)
                                                                                                                                                  return true;
                                                                                                                                          }
                                                                                                                                          return false;
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsAtom(Noun noun)
                                                                                                                                      {
                                                                                                                                          return IsAtom(noun.ToString());
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static bool IsCell(Noun noun)
                                                                                                                                      {
                                                                                                                                          return IsCell(noun.ToString());
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun CreateNoun(string program)
                                                                                                                                      {
                                                                                                                                          if (IsAtom(program))
                                                                                                                                              return new Atom(program);
                                                                                                                                          else
                                                                                                                                              return new Cell(program);
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun CreateNoun(Noun n1, Noun n2)
                                                                                                                                      {
                                                                                                                                          return CreateNoun("[" + n1.ToString() + " " + n2.ToString() + "]");
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun CreateNoun(string p1, Noun n2)
                                                                                                                                      {
                                                                                                                                          return CreateNoun("[" + p1 + " " + n2.ToString() + "]");
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun CreateNoun(Noun n1, string p2)
                                                                                                                                      {
                                                                                                                                          return CreateNoun("[" + n1.ToString() + " " + p2 + "]");
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public static Noun CreateNoun(string p1, string p2)
                                                                                                                                      {
                                                                                                                                          return CreateNoun("[" + p1 + " " + p2 + "]");
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  class Atom : Noun
                                                                                                                                  {
                                                                                                                                      public int value;
                                                                                                                              
                                                                                                                                      public override string ToString()
                                                                                                                                      {
                                                                                                                                          return value.ToString();
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public Atom(string program)
                                                                                                                                      {
                                                                                                                                          if (IsAtom(program))
                                                                                                                                          {
                                                                                                                                              int i = 0;
                                                                                                                                              bool result = int.TryParse(program, out i);
                                                                                                                                              value = i;
                                                                                                                                          }
                                                                                                                                          else
                                                                                                                                              throw new ArgumentException("Invalid Atom: " + program);
                                                                                                                                          n1 = null;
                                                                                                                                          n2 = null;
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  class Cell : Noun
                                                                                                                                  {
                                                                                                                                      public override string ToString()
                                                                                                                                      {
                                                                                                                                          return "[" + n1.ToString() + " " + n2.ToString() + "]";
                                                                                                                                      }
                                                                                                                              
                                                                                                                                      public Cell(string program)
                                                                                                                                      {
                                                                                                                                          if (IsCell(program))
                                                                                                                                          {
                                                                                                                                              Tuple<string, string> split = SplitCell(program);
                                                                                                                                              n1 = CreateNoun(split.Item1);
                                                                                                                                              n2 = CreateNoun(split.Item2);
                                                                                                                                          }
                                                                                                                                          else
                                                                                                                                              throw new ArgumentException("Invalid Cell: " + program);
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }

                                                                                                                              Groovy

                                                                                                                              From Kohányi Róbert:

                                                                                                                              @Memoized
                                                                                                                              def i(def a) {
                                                                                                                                a.class in [
                                                                                                                                  byte, Byte,
                                                                                                                                  char, Character,
                                                                                                                                  short, Short,
                                                                                                                                  int, Integer,
                                                                                                                                  long, Long,
                                                                                                                                  BigInteger
                                                                                                                                ] && a >= 0
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def n(def a) {
                                                                                                                                def r
                                                                                                                                n(a, { r = it })
                                                                                                                                r
                                                                                                                              }
                                                                                                                              
                                                                                                                              @TailRecursive
                                                                                                                              def n(def a, def r) {
                                                                                                                                if (a in List) {
                                                                                                                                  if (a.size() == 1) {
                                                                                                                                    r(a[0])
                                                                                                                                  } else if (a.size() >= 2) {
                                                                                                                                    n(a[0], { t ->
                                                                                                                                      n(a.size() == 2 ? a[1] : a.tail(), { h ->
                                                                                                                                        r([t, h])
                                                                                                                                      })
                                                                                                                                    })
                                                                                                                                  } else {
                                                                                                                                    throw new IllegalStateException()
                                                                                                                                  }
                                                                                                                                } else if (i(a)) {
                                                                                                                                  r((BigInteger) a)
                                                                                                                                } else {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def wut(def a) {
                                                                                                                                i(a) ? 1 : 0
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def lus(def a) {
                                                                                                                                if (wut(a) == 0) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                1 + a
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def tis(def a) {
                                                                                                                                if (wut(a) == 1) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                a[0] == a[1] ? 0 : 1
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def fas(def a) {
                                                                                                                                def r
                                                                                                                                fas(a, { r = it })
                                                                                                                                r
                                                                                                                              }
                                                                                                                              
                                                                                                                              @TailRecursive
                                                                                                                              def fas(def a, def r) {
                                                                                                                                if (wut(a) == 1) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                def h = a[0]
                                                                                                                                if (!i(h)) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                def t = a[1]
                                                                                                                                if (h == 0) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                } else if (h == 1) {
                                                                                                                                  r(t)
                                                                                                                                } else {
                                                                                                                                  if (i(t)) {
                                                                                                                                    throw new IllegalStateException()
                                                                                                                                  }
                                                                                                                                  if (h == 2) {
                                                                                                                                    r(t[0])
                                                                                                                                  } else if (h == 3) {
                                                                                                                                    r(t[1])
                                                                                                                                  } else {
                                                                                                                                    fas([h.intdiv(2), t], { p ->
                                                                                                                                      fas([2 + h.mod(2), p], { q ->
                                                                                                                                        r(q)
                                                                                                                                      })
                                                                                                                                    })
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              }
                                                                                                                              
                                                                                                                              @Memoized
                                                                                                                              def tar(def a) {
                                                                                                                                def r
                                                                                                                                tar(a, { r = it})
                                                                                                                                r
                                                                                                                              }
                                                                                                                              
                                                                                                                              @TailRecursive
                                                                                                                              def tar(def a, def r) {
                                                                                                                                if (wut(a) == 1) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                def s = a[0]
                                                                                                                                def f = a[1]
                                                                                                                                if (wut(f) == 1) {
                                                                                                                                  throw new IllegalStateException()
                                                                                                                                }
                                                                                                                                def o = f[0]
                                                                                                                                def v = f[1]
                                                                                                                                if (wut(o) == 0) {
                                                                                                                                  tar([s, o], { p ->
                                                                                                                                    tar([s, v], { q ->
                                                                                                                                      r([p, q])
                                                                                                                                    })
                                                                                                                                  })
                                                                                                                                } else {
                                                                                                                                  if (o == 0) {
                                                                                                                                    r(fas([v, s]))
                                                                                                                                  } else if (o == 1) {
                                                                                                                                    r(v)
                                                                                                                                  } else if (o == 3) {
                                                                                                                                    tar([s, v], {
                                                                                                                                      r(wut(it))
                                                                                                                                    })
                                                                                                                                  } else if (o == 4) {
                                                                                                                                    tar([s, v], {
                                                                                                                                      r(lus(it))
                                                                                                                                    })
                                                                                                                                  } else if (o == 5) {
                                                                                                                                    tar([s, v], {
                                                                                                                                      r(tis(it))
                                                                                                                                    })
                                                                                                                                  } else {
                                                                                                                                    if (wut(v) == 1) {
                                                                                                                                      throw new IllegalStateException()
                                                                                                                                    }
                                                                                                                                    def x = v[0]
                                                                                                                                    def y = v[1]
                                                                                                                                    if (o == 2) {
                                                                                                                                      tar([s, x], { p ->
                                                                                                                                        tar([s, y], { q ->
                                                                                                                                          tar([p, q], {
                                                                                                                                            r(it)
                                                                                                                                          })
                                                                                                                                        })
                                                                                                                                      })
                                                                                                                                    } else if (o == 7) {
                                                                                                                                      tar(n([s, 2, x, 1, y]), {
                                                                                                                                        r(it)
                                                                                                                                      })
                                                                                                                                    } else if (o == 8) {
                                                                                                                                      tar(n([s, 7, [[7, [0, 1], x], 0, 1], y]), {
                                                                                                                                        r(it)
                                                                                                                                      })
                                                                                                                                    } else if (o == 9) {
                                                                                                                                      tar(n([s, 7, y, 2, [0, 1], 0, x]), {
                                                                                                                                        r(it)
                                                                                                                                      })
                                                                                                                                    } else if (o == 10) {
                                                                                                                                      if (wut(x) == 1) {
                                                                                                                                        tar([s, y], {
                                                                                                                                          r(it)
                                                                                                                                        })
                                                                                                                                      } else {
                                                                                                                                        tar(n([s, 8, x[1], 7, [0, 3], y]), {
                                                                                                                                          r(it)
                                                                                                                                        })
                                                                                                                                      }
                                                                                                                                    } else {
                                                                                                                                      if (wut(y) == 1) {
                                                                                                                                        throw new IllegalStateException()
                                                                                                                                      }
                                                                                                                                      if (o == 6) {
                                                                                                                                        tar(n([s, 2, [0, 1], 2, [1, y[0], y[1]], [1, 0], 2, [1, 2, 3], [1, 0], 4, 4, x]), {
                                                                                                                                          r(it)
                                                                                                                                        })
                                                                                                                                      } else {
                                                                                                                                        throw new IllegalStateException()
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              }

                                                                                                                              Haskell

                                                                                                                              From Steve Dee:

                                                                                                                              module Language.Nock5K.Spec where
                                                                                                                              import Control.Monad.Instances
                                                                                                                              
                                                                                                                              wut (a :- b)                         = return $ Atom 0
                                                                                                                              wut a                                = return $ Atom 1
                                                                                                                              
                                                                                                                              lus (a :- b)                         = Left "+[a b]"
                                                                                                                              lus (Atom a)                         = return $ Atom (1 + a)
                                                                                                                              
                                                                                                                              tis (a :- a') | a == a'              = return $ Atom 0
                                                                                                                              tis (a :- b)                         = return $ Atom 1
                                                                                                                              tis a                                = Left "=a"
                                                                                                                              
                                                                                                                              fas (Atom 1 :- a)                    = return a
                                                                                                                              fas (Atom 2 :- a :- b)               = return a
                                                                                                                              fas (Atom 3 :- a :- b)               = return b
                                                                                                                              fas (Atom a :- b) | a > 3            = do  x <- fas $ Atom (a `div` 2) :- b
                                                                                                                                                                         fas $ Atom (2 + (a `mod` 2)) :- x
                                                                                                                              fas a                                = Left "/a"
                                                                                                                              
                                                                                                                              tar (a :- (b :- c) :- d)             = do x <- tar (a :- b :- c)
                                                                                                                                                                        y <- tar (a :- d)
                                                                                                                                                                        return $ x :- y
                                                                                                                              
                                                                                                                              tar (a :- Atom 0 :- b)               = fas $ b :- a
                                                                                                                              tar (a :- Atom 1 :- b)               = return b
                                                                                                                              tar (a :- Atom 2 :- b :- c)          = do  x <- tar (a :- b)
                                                                                                                                                                         y <- tar (a :- c)
                                                                                                                                                                         tar $ x :- y
                                                                                                                              tar (a :- Atom 3 :- b)               = tar (a :- b) >>= wut
                                                                                                                              tar (a :- Atom 4 :- b)               = tar (a :- b) >>= lus
                                                                                                                              tar (a :- Atom 5 :- b)               = tar (a :- b) >>= tis
                                                                                                                              
                                                                                                                              tar (a :- Atom 6 :- b :- c :- d)     = tar (a :- Atom 2 :- (Atom 0 :- Atom 1) :-
                                                                                                                                                                          Atom 2 :- (Atom 1 :- c :- d) :-
                                                                                                                                                                          (Atom 1 :- Atom 0) :- Atom 2 :-
                                                                                                                                                                          (Atom 1 :- Atom 2 :- Atom 3) :-
                                                                                                                                                                          (Atom 1 :- Atom 0) :- Atom 4 :-
                                                                                                                                                                          Atom 4 :- b)
                                                                                                                              tar (a :- Atom 7 :- b :- c)          = tar (a :- Atom 2 :- b :- Atom 1 :- c)
                                                                                                                              tar (a :- Atom 8 :- b :- c)          = tar (a :- Atom 7 :-
                                                                                                                                                                          ((Atom 7 :- (Atom 0 :- Atom 1) :- b) :-
                                                                                                                                                                           Atom 0 :- Atom 1) :- c)
                                                                                                                              tar (a :- Atom 9 :- b :- c)          = tar (a :- Atom 7 :- c :- Atom 2 :-
                                                                                                                                                                          (Atom 0 :- Atom 1) :- Atom 0 :- b)
                                                                                                                              tar (a :- Atom 10 :- (b :- c) :- d)  = tar (a :- Atom 8 :- c :- Atom 7 :-
                                                                                                                                                                          (Atom 0 :- Atom 3) :- d)
                                                                                                                              tar (a :- Atom 10 :- b :- c)         = tar (a :- c)
                                                                                                                              
                                                                                                                              tar a                                = Left "*a"

                                                                                                                              Hoon

                                                                                                                              |=  {sub/* fol/*}
                                                                                                                              ^-  *
                                                                                                                              ?<  ?=(@ fol)
                                                                                                                              ?:  ?=(^ -.fol)
                                                                                                                                [$(fol -.fol) $(fol +.fol)]
                                                                                                                              ?+    fol
                                                                                                                                !!
                                                                                                                                  {$0 b/@}
                                                                                                                                ?<  =(0 b.fol)
                                                                                                                                ?:  =(1 b.fol)  sub
                                                                                                                                ?<  ?=(@ sub)
                                                                                                                                =+  [now=(cap b.fol) lat=(mas b.fol)]
                                                                                                                                $(b.fol lat, sub ?:(=(2 now) -.sub +.sub))
                                                                                                                              ::
                                                                                                                                  {$1 b/*}
                                                                                                                                b.fol
                                                                                                                              ::
                                                                                                                                  {$2 b/{^ *}}
                                                                                                                                =+  ben=$(fol b.fol)
                                                                                                                                $(sub -.ben, fol +.ben)
                                                                                                                              ::
                                                                                                                                  {$3 b/*}
                                                                                                                                =+  ben=$(fol b.fol)
                                                                                                                                .?(ben)
                                                                                                                              ::
                                                                                                                                  {$4 b/*}
                                                                                                                                =+  ben=$(fol b.fol)
                                                                                                                                ?>  ?=(@ ben)
                                                                                                                                +(ben)
                                                                                                                              ::
                                                                                                                                  {$5 b/*}
                                                                                                                                =+  ben=$(fol b.fol)
                                                                                                                                ?>  ?=(^ ben)
                                                                                                                                =(-.ben +.ben)
                                                                                                                              ::
                                                                                                                                  {$6 b/* c/* d/*}
                                                                                                                                $(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]))
                                                                                                                              ::
                                                                                                                                  {$7 b/* c/*}         $(fol =>(fol [2 b 1 c]))
                                                                                                                                  {$8 b/* c/*}         $(fol =>(fol [7 [[7 [0 1] b] 0 1] c]))
                                                                                                                                  {$9 b/* c/*}         $(fol =>(fol [7 c 2 [0 1] 0 b]))
                                                                                                                                  {$10 @ c/*}          $(fol c.fol)
                                                                                                                                  {$10 {b/* c/*} d/*}  =+($(fol c.fol) $(fol d.fol))
                                                                                                                              ==
                                                                                                                              

                                                                                                                              JavaScript

                                                                                                                              From Joe Bryan:

                                                                                                                              (function (self, factory) {
                                                                                                                                'use strict'
                                                                                                                              
                                                                                                                                if (typeof define === 'function' && define.amd) {
                                                                                                                                  define([], factory)
                                                                                                                                } else if (typeof module === 'object' && typeof module.exports === 'object') {
                                                                                                                                  module.exports = factory()
                                                                                                                                } else {
                                                                                                                                  self.nock = factory()
                                                                                                                                }
                                                                                                                              }(this, function () {
                                                                                                                                'use strict'
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * Nock is a combinator interpreter on nouns. A noun is an atom or a cell.
                                                                                                                                 * An atom is an unsigned integer of any size; a cell is an ordered pair of nouns.
                                                                                                                                 *
                                                                                                                                 * @see http://urbit.org/docs/nock/definition/
                                                                                                                                 * @see https://media.urbit.org/whitepaper.pdf
                                                                                                                                 */
                                                                                                                              
                                                                                                                                var useMacros = false
                                                                                                                              
                                                                                                                                /*
                                                                                                                                 *  code conventions:
                                                                                                                                 *
                                                                                                                                 *    `n` is a noun,
                                                                                                                                 *    `s` is a subject noun,
                                                                                                                                 *    `f` is a formula (or cell of formulas)
                                                                                                                                 */
                                                                                                                              
                                                                                                                                /*  operators  */
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * wut (?): test for atom (1) or cell (0)
                                                                                                                                 *
                                                                                                                                 *   ?[a b]           0
                                                                                                                                 *   ?a               1
                                                                                                                                 */
                                                                                                                                function wut (n) {
                                                                                                                                  return typeof n === 'number' ? 1 : 0
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * lus (+): increment an atom
                                                                                                                                 *
                                                                                                                                 *   +[a b]           +[a b]
                                                                                                                                 *   +a               1 + a
                                                                                                                                 */
                                                                                                                                function lus (n) {
                                                                                                                                  if (wut(n) === 0) throw new Error('lus cell')
                                                                                                                                  return 1 + n
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * tis (=): test equality
                                                                                                                                 *
                                                                                                                                 *   =[a a]           0
                                                                                                                                 *   =[a b]           1
                                                                                                                                 *   =a               =a
                                                                                                                                 */
                                                                                                                                function tis (n) {
                                                                                                                                  if (wut(n) === 1) throw new Error('tis atom')
                                                                                                                                  return deepEqual(n[0], n[1]) ? 0 : 1
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * fas (/): resolve a tree address
                                                                                                                                 *
                                                                                                                                 *   /[1 a]           a
                                                                                                                                 *   /[2 a b]         a
                                                                                                                                 *   /[3 a b]         b
                                                                                                                                 *   /[(a + a) b]     /[2 /[a b]]
                                                                                                                                 *   /[(a + a + 1) b] /[3 /[a b]]
                                                                                                                                 *   /a               /a
                                                                                                                                 */
                                                                                                                                function fas (addr, n) {
                                                                                                                                  if (n === undefined) throw new Error('invalid fas noun')
                                                                                                                                  if (addr === 0) throw new Error('invalid fas addr: 0')
                                                                                                                              
                                                                                                                                  if (addr === 1) return n
                                                                                                                                  if (addr === 2) return n[0]
                                                                                                                                  if (addr === 3) return n[1]
                                                                                                                              
                                                                                                                                  return fas(2 + (addr % 2), fas((addr / 2) | 0, n))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /*  formulas  */
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * slot (0): resolve a tree address
                                                                                                                                 *
                                                                                                                                 *   *[a 0 b]         /[b a]
                                                                                                                                 */
                                                                                                                                function slot (s, f) {
                                                                                                                                  var p = fas(f, s)
                                                                                                                              
                                                                                                                                  if (p === undefined) throw new Error('invalid fas addr: ' + f)
                                                                                                                              
                                                                                                                                  return p
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * constant (1): return the formula regardless of subject
                                                                                                                                 *
                                                                                                                                 *   *[a 1 b]  b
                                                                                                                                 */
                                                                                                                                function constant (s, f) {
                                                                                                                                  return f
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * evaluate (2): evaluate the product of second formula against the product of the first
                                                                                                                                 *
                                                                                                                                 *   *[a 2 b c]  *[*[a b] *[a c]]
                                                                                                                                 */
                                                                                                                                function evaluate (s, f) {
                                                                                                                                  return nock(nock(s, f[0]), nock(s, f[1]))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * cell (3): test if the product is a cell
                                                                                                                                 *
                                                                                                                                 *   *[a 3 b]         ?*[a b]
                                                                                                                                 */
                                                                                                                                function cell (s, f) {
                                                                                                                                  return wut(nock(s, f))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 *  incr (4): increment the product
                                                                                                                                 *
                                                                                                                                 *   *[a 4 b]         +*[a b]
                                                                                                                                 */
                                                                                                                                function incr (s, f) {
                                                                                                                                  return lus(nock(s, f))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * eq (5): test for equality between nouns in the product
                                                                                                                                 *
                                                                                                                                 *   *[a 5 b]         =*[a b]
                                                                                                                                 */
                                                                                                                                function eq (s, f) {
                                                                                                                                  return tis(nock(s, f))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /*  macro-formulas  */
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * ife (6): if/then/else
                                                                                                                                 *
                                                                                                                                 *   *[a 6 b c d]      *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
                                                                                                                                 */
                                                                                                                                function macroIfe (s, f) {
                                                                                                                                  return nock(s, [2, [[0, 1], [2, [[1, [f[1][0], f[1][1]]], [[1, 0], [2, [[1, [2, 3]], [[1, 0], [4, [4, f[0]]]]]]]]]]])
                                                                                                                                }
                                                                                                                              
                                                                                                                                function ife (s, f) {
                                                                                                                                  var cond = nock(s, f[0])
                                                                                                                              
                                                                                                                                  if (cond === 0) return nock(s, f[1][0])
                                                                                                                                  if (cond === 1) return nock(s, f[1][1])
                                                                                                                              
                                                                                                                                  throw new Error('invalid ife conditional')
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * compose (7): evaluate formulas composed left-to-right
                                                                                                                                 *
                                                                                                                                 *   *[a 7 b c]  *[a 2 b 1 c]
                                                                                                                                 */
                                                                                                                                function macroCompose (s, f) {
                                                                                                                                  return nock(s, [2, [f[0], [1, f[1]]]])
                                                                                                                                }
                                                                                                                              
                                                                                                                                function compose (s, f) {
                                                                                                                                  // alternate form:
                                                                                                                                  // return nock(nock(s, f[0]), constant(s, f[1]))
                                                                                                                                  return nock(nock(s, f[0]), f[1])
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * extend (8): evaluate the second formula against [product of first, subject]
                                                                                                                                 *
                                                                                                                                 *   *[a 8 b c]  *[a 7 [[7 [0 1] b] 0 1] c]
                                                                                                                                 */
                                                                                                                                function macroExtend (s, f) {
                                                                                                                                  return nock(s, [7, [[[7, [[0, 1], f[0]]], [0, 1]], f[1]]])
                                                                                                                                }
                                                                                                                              
                                                                                                                                function extend (s, f) {
                                                                                                                                  // alternate form:
                                                                                                                                  // return nock([compose(s, [[0, 1], f[0]]), s], f[1])
                                                                                                                                  return nock([nock(s, f[0]), s], f[1])
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * invoke (9): construct a core and evaluate one of its arms against it
                                                                                                                                 *
                                                                                                                                 *   *[a 9 b c]  *[a 7 c 2 [0 1] 0 b]
                                                                                                                                 */
                                                                                                                                function macroInvoke (s, f) {
                                                                                                                                  return nock(s, [7, [f[1], [2, [[0, 1], [0, f[0]]]]]])
                                                                                                                                }
                                                                                                                              
                                                                                                                                function invoke (s, f) {
                                                                                                                                  var prod = nock(s, f[1])
                                                                                                                                  return nock(prod, slot(prod, f[0]))
                                                                                                                                }
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * hint (10): skip first formula, evaluate second
                                                                                                                                 *
                                                                                                                                 *   *[a 10 [b c] d]  *[a 8 c 7 [0 3] d]
                                                                                                                                 *   *[a 10 b c]      *[a c]
                                                                                                                                 */
                                                                                                                                function macroHint (s, f) {
                                                                                                                                  if (wut(f[0]) === 0) return nock(s, [8, [f[0][1], [7, [[0, 3], f[1]]]]])
                                                                                                                                  return nock(s, f[1])
                                                                                                                                }
                                                                                                                              
                                                                                                                                function hint (s, f) {
                                                                                                                                  if (wut(f[0]) === 0) {
                                                                                                                                    if (wut(f[0][1]) === 1) throw new Error('invalid hint')
                                                                                                                                    nock(s, f[0][1])
                                                                                                                                  }
                                                                                                                                  return nock(s, f[1])
                                                                                                                                }
                                                                                                                              
                                                                                                                                /*  indexed formula functions  */
                                                                                                                                var macroFormulas = [slot, constant, evaluate, cell, incr, eq, macroIfe, macroCompose, macroExtend, macroInvoke, macroHint]
                                                                                                                                var formulas = [slot, constant, evaluate, cell, incr, eq, ife, compose, extend, invoke, hint]
                                                                                                                              
                                                                                                                                /**
                                                                                                                                 * nock (*)
                                                                                                                                 *
                                                                                                                                 * the nock function
                                                                                                                                 *
                                                                                                                                 *   *[a [b c] d]     [*[a b c] *[a d]]
                                                                                                                                 *   *a               *a
                                                                                                                                 */
                                                                                                                                function nock (s, f) {
                                                                                                                                  if (wut(f[0]) === 0) return [nock(s, f[0]), nock(s, f[1])]
                                                                                                                              
                                                                                                                                  var idx = f[0]
                                                                                                                              
                                                                                                                                  if (idx > 10) throw new Error('invalid formula: ' + idx)
                                                                                                                              
                                                                                                                                  if (useMacros) return macroFormulas[idx](s, f[1])
                                                                                                                              
                                                                                                                                  return formulas[idx](s, f[1])
                                                                                                                                }
                                                                                                                              
                                                                                                                                /* construct a JS noun (group an array into pairs, associating right) */
                                                                                                                                function assoc (x) {
                                                                                                                                  if (!x.length) return x
                                                                                                                              
                                                                                                                                  if (x.length === 1) return assoc(x[0])
                                                                                                                              
                                                                                                                                  return [assoc(x[0]), assoc(x.slice(1))]
                                                                                                                                }
                                                                                                                              
                                                                                                                                /* deep equality for arrays or primitives */
                                                                                                                                function deepEqual (a, b) {
                                                                                                                                  if (a === b) return true
                                                                                                                              
                                                                                                                                  if (!(Array.isArray(a) && Array.isArray(b))) return false
                                                                                                                                  if (a.length !== b.length) return false
                                                                                                                              
                                                                                                                                  for (var i = 0; i < a.length; i++) {
                                                                                                                                    if (!deepEqual(a[i], b[i])) return false
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  return true
                                                                                                                                }
                                                                                                                              
                                                                                                                                /* parse a hoon-serialized nock formula and construct a JS noun */
                                                                                                                                function parseNoun (x) {
                                                                                                                                  if (Array.isArray(x)) return assoc(x)
                                                                                                                              
                                                                                                                                  if (typeof x === 'string') {
                                                                                                                                    var str = x.replace(/[\."']/g, '').split(' ').join(',')
                                                                                                                                    return assoc(JSON.parse(str))
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  return x
                                                                                                                                }
                                                                                                                              
                                                                                                                                function nockInterface () {
                                                                                                                                  var args = [].slice.call(arguments)
                                                                                                                                  var subject, formula, noun
                                                                                                                              
                                                                                                                                  if (args.length === 1) {
                                                                                                                                    formula = parseNoun(args[0])
                                                                                                                                  } else if (args.length === 2) {
                                                                                                                                    subject = parseNoun(args[0])
                                                                                                                                    formula = parseNoun(args[1])
                                                                                                                                  } else {
                                                                                                                                    noun = assoc(args)
                                                                                                                                    subject = noun[0]
                                                                                                                                    formula = noun[1]
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  if (!formula) throw new Error('formula required')
                                                                                                                              
                                                                                                                                  if (!subject) {
                                                                                                                                    // !=(~)
                                                                                                                                    subject = [1, 0]
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  return nock(subject, formula)
                                                                                                                                }
                                                                                                                              
                                                                                                                                return {
                                                                                                                                  nock: nockInterface,
                                                                                                                                  _nock: nock,
                                                                                                                                  useMacros: function (arg) {
                                                                                                                                    useMacros = arg === undefined || arg
                                                                                                                                    return this
                                                                                                                                  },
                                                                                                                                  util: {
                                                                                                                                    assoc: assoc,
                                                                                                                                    parseNoun: parseNoun,
                                                                                                                                    deepEqual: deepEqual
                                                                                                                                  },
                                                                                                                                  operators: {
                                                                                                                                    wut: wut,
                                                                                                                                    lus: lus,
                                                                                                                                    tis: tis,
                                                                                                                                    fas: fas
                                                                                                                                  },
                                                                                                                                  formulas: {
                                                                                                                                    slot: slot,
                                                                                                                                    constant: constant,
                                                                                                                                    evaluate: evaluate,
                                                                                                                                    cell: cell,
                                                                                                                                    incr: incr,
                                                                                                                                    eq: eq,
                                                                                                                                    macroIfe: macroIfe,
                                                                                                                                    ife: ife,
                                                                                                                                    macroCompose: macroCompose,
                                                                                                                                    compose: compose,
                                                                                                                                    macroExtend: macroExtend,
                                                                                                                                    extend: extend,
                                                                                                                                    macroInvoke: macroInvoke,
                                                                                                                                    invoke: invoke,
                                                                                                                                    macroHint: macroHint,
                                                                                                                                    hint: hint
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              }))
                                                                                                                              

                                                                                                                              Python

                                                                                                                              From James Tauber:

                                                                                                                              #!/usr/bin/env python3
                                                                                                                              
                                                                                                                              # []
                                                                                                                              def l(*lst):
                                                                                                                                  if len(lst) == 1:
                                                                                                                                      return(lst[0], 0)
                                                                                                                                  if len(lst) == 2:
                                                                                                                                      return lst
                                                                                                                                  else:
                                                                                                                                      return (lst[0], l(*lst[1:]))
                                                                                                                              
                                                                                                                              # *
                                                                                                                              def nock(noun):
                                                                                                                                  return tar(noun)
                                                                                                                              
                                                                                                                              # ?
                                                                                                                              def wut(noun):
                                                                                                                                  if isinstance(noun, int):
                                                                                                                                      return 1
                                                                                                                                  else:
                                                                                                                                      return 0
                                                                                                                              
                                                                                                                              
                                                                                                                              # +
                                                                                                                              def lus(noun):
                                                                                                                                  if isinstance(noun, int):
                                                                                                                                      return 1 + noun
                                                                                                                                  else:
                                                                                                                                      return noun
                                                                                                                              
                                                                                                                              
                                                                                                                              # =
                                                                                                                              def tis(noun):
                                                                                                                                  if noun[0] == noun[1]:
                                                                                                                                      return 0
                                                                                                                                  else:
                                                                                                                                      return 1
                                                                                                                              
                                                                                                                              
                                                                                                                              # /
                                                                                                                              def slot(noun):
                                                                                                                                  if noun[0] == 1:
                                                                                                                                      return noun[1]
                                                                                                                                  elif noun[0] == 2:
                                                                                                                                      return noun[1][0]
                                                                                                                                  elif noun[0] == 3:
                                                                                                                                      return noun[1][1]
                                                                                                                                  elif noun[0] % 2 == 0:
                                                                                                                                      return slot((2, slot((noun[0] // 2, noun[1]))))
                                                                                                                                  elif noun[0] % 2 == 1:
                                                                                                                                      return slot((3, slot(((noun[0] - 1) // 2, noun[1]))))
                                                                                                                              
                                                                                                                              
                                                                                                                              def tar(noun):
                                                                                                                                  if isinstance(noun[1][0], int):
                                                                                                                                      if noun[1][0] == 0:
                                                                                                                                          return slot((noun[1][1], noun[0]))
                                                                                                                                      elif noun[1][0] == 1:
                                                                                                                                          return noun[1][1]
                                                                                                                                      elif noun[1][0] == 2:
                                                                                                                                          return nock((nock((noun[0], noun[1][1][0])), nock((noun[0], noun[1][1][1]))))
                                                                                                                                      elif noun[1][0] == 3:
                                                                                                                                          return wut(nock((noun[0], noun[1][1])))
                                                                                                                                      elif noun[1][0] == 4:
                                                                                                                                          return lus(nock((noun[0], noun[1][1])))
                                                                                                                                      elif noun[1][0] == 5:
                                                                                                                                          return tis(nock((noun[0], noun[1][1])))
                                                                                                                                      elif noun[1][0] == 6:
                                                                                                                                          return nock(l(noun[0], 2, (0, 1), 2, l(1, noun[1][1][1][0], noun[1][1][1][1]), (1, 0), 2, l(1, 2, 3), (1, 0), 4, 4, noun[1][1][0]))
                                                                                                                                      elif noun[1][0] == 7:
                                                                                                                                          return nock(l(noun[0], 2, noun[1][1][0], 1, noun[1][1][1]))
                                                                                                                                      elif noun[1][0] == 8:
                                                                                                                                          return nock(l(noun[0], 7, l(l(7, (0, 1), noun[1][1][0]), 0, 1), noun[1][1][1]))
                                                                                                                                      elif noun[1][0] == 9:
                                                                                                                                          return nock(l(noun[0], 7, noun[1][1][1], l(2, (0, 1), (0, noun[1][1][0]))))
                                                                                                                                      elif noun[1][0] == 10:
                                                                                                                                          if isinstance(noun[1][1][0], int):
                                                                                                                                              return nock((noun[0], noun[1][1][1]))
                                                                                                                                          else:
                                                                                                                                              return nock(l(noun[0], 8, noun[1][1][0][1], 7, (0, 3), noun[1][1][1][0]))
                                                                                                                                  else:
                                                                                                                                      return (nock((noun[0], noun[1][0])), nock((noun[0], noun[1][1])))
                                                                                                                              

                                                                                                                              Ruby

                                                                                                                              From T.J. Corcoran:

                                                                                                                              def str_to_tree(str)
                                                                                                                                arr = []
                                                                                                                                str.scan(/\+|\=|\?|\/|\*|\[|\]|\d+/).each do |token|
                                                                                                                                end
                                                                                                                              end
                                                                                                                              
                                                                                                                              def max_depth(arr)
                                                                                                                                ret = arr.is_a?(Array) ?  [max_depth(arr[0]), max_depth(arr[1])].max + 1 : 1
                                                                                                                                ret
                                                                                                                              end
                                                                                                                              
                                                                                                                              def pp(arr)
                                                                                                                                depth = max_depth(arr)
                                                                                                                                space = 128
                                                                                                                                1.up_to(8) do |depth|
                                                                                                                                  space = space / 2
                                                                                                                                  min = 2 ** (depth - 1)
                                                                                                                                  max = (2 ** depth) - 1
                                                                                                                                  min.upto(max) { |axis|
                                                                                                                                end
                                                                                                                              
                                                                                                                              end
                                                                                                                              
                                                                                                                              def norm(arr)
                                                                                                                                return arr unless arr.is_a?(Array)
                                                                                                                                while arr.size > 2
                                                                                                                                  size = arr.size
                                                                                                                                  arr[size - 2] = [ arr[size - 2], arr.pop ]
                                                                                                                                end
                                                                                                                                arr = arr.map { |x| norm(x)   }
                                                                                                                              end
                                                                                                                              
                                                                                                                              def wut(arr)
                                                                                                                                arr.is_a?(Array) ? YES : NO
                                                                                                                              end
                                                                                                                              
                                                                                                                              def lus(atom)
                                                                                                                                raise "not an atom" unless atom.is_a?(Fixnum)
                                                                                                                                atom + 1
                                                                                                                              end
                                                                                                                              
                                                                                                                              def tis(arr)
                                                                                                                                raise "not pair" unless arr.is_a?(Array) && arr.size == 2
                                                                                                                                ( arr[0] == arr[1] ) ? YES : NO
                                                                                                                              end
                                                                                                                              
                                                                                                                              def slot(axis, arr, allow_error = true)
                                                                                                                                raise "axis on atom" unless arr.is_a?(Array)
                                                                                                                                return arr if axis == 1
                                                                                                                                return arr[0] if axis == 2
                                                                                                                                return arr[1] if axis == 3
                                                                                                                                return slot(2, slot(axis/2, arr))   if (axis %2) == 0
                                                                                                                                return slot(3, slot(axis/2, arr))
                                                                                                                              end
                                                                                                                              
                                                                                                                              
                                                                                                                              def nock(arr)
                                                                                                                                raise "error: nocking an atom" unless arr.is_a?(Array)
                                                                                                                              
                                                                                                                                oper = slot(4, arr)
                                                                                                                                a    = slot(2, arr)
                                                                                                                                b    = slot(5, arr)
                                                                                                                              
                                                                                                                                if oper.is_a?(Array)
                                                                                                                                  return  [ nock( [ a, [b, c]]), nock( [a, d]) ]
                                                                                                                                end
                                                                                                                              
                                                                                                                              
                                                                                                                                case oper
                                                                                                                                  when 0 then
                                                                                                                                  slot(b,a )
                                                                                                                              
                                                                                                                                  when 1 then
                                                                                                                                  b
                                                                                                                              
                                                                                                                                  when 2 then
                                                                                                                                  b_prime = slot(2, b)
                                                                                                                                  c       = slot(3,b)
                                                                                                                                  nock( [ nock([a, b_primce]), nock([a, c]) ])
                                                                                                                              
                                                                                                                                  when 3 then
                                                                                                                                  wut(nock([a, b]))
                                                                                                                              
                                                                                                                                  when 4 then
                                                                                                                                  lus(nock([a, b]))
                                                                                                                              
                                                                                                                                  when 5 then
                                                                                                                                  tis(nock([a, b]))
                                                                                                                              
                                                                                                                                  when 6 then
                                                                                                                                  b_prime = slot(2, b)
                                                                                                                                  c = slot(6,b)
                                                                                                                                  d = slot(7,b)
                                                                                                                                  nock( norm([a, 2, [0, 1], 2, [1, c, d], [1, 0], 2, [1, 2, 3], [1, 0], 4, 4, b]) )
                                                                                                                              
                                                                                                                                  when 7 then
                                                                                                                                  b_prime = slot(2, b)
                                                                                                                                  c = slot(3,b)
                                                                                                                                  nock( norm ([a, 2, b_prime, 1, c]))
                                                                                                                              
                                                                                                                                  when 8 then
                                                                                                                                  b_prime = slot(2, b)
                                                                                                                                  c = slot(3,b)
                                                                                                                                  nock( norm ([a, 7, [[7, [0, 1], b_prime], 0, 1], c]))
                                                                                                                              
                                                                                                                                  when 9 then
                                                                                                                                  b_prime = slot(2, b)
                                                                                                                                  c = slot(3,b)
                                                                                                                                  nock( norm ([a, 7, c, 2, [0, 1], 0, b_prime]))
                                                                                                                              
                                                                                                                                  when 10 then
                                                                                                                                  if wut(slot(2,b)) == TRUE
                                                                                                                                    b_prime = slot(4, b)
                                                                                                                                    c       = slot(5, b)
                                                                                                                                    d       = slot(3, b)
                                                                                                                                    c = slot(3,b)
                                                                                                                                    nock( norm ([a, 8, c, 7, [0, 3], d]))
                                                                                                                                  else
                                                                                                                                    b_prime = slot(2, b)
                                                                                                                                    c       = slot(3, b)
                                                                                                                                    nock( norm ([a, 10, [b, c]]))
                                                                                                                                  end
                                                                                                                                  else
                                                                                                                                    raise "error: unknown opcode #{oper.inspect}"
                                                                                                                                  end
                                                                                                                              end
                                                                                                                              

                                                                                                                              Rust

                                                                                                                              From Peter McEvoy:

                                                                                                                              #![allow(unused_parens)]
                                                                                                                              
                                                                                                                              use std::{error, fmt};
                                                                                                                              
                                                                                                                              #[derive(Debug)]
                                                                                                                              enum Noun {
                                                                                                                                  Atom(Atom),
                                                                                                                                  Cell(Cell),
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Clone for Noun {
                                                                                                                                  fn clone(&self) -> Self {
                                                                                                                                      match self {
                                                                                                                                          Noun::Atom(a) => Noun::Atom(Atom(a.0)),
                                                                                                                                          Noun::Cell(c) => Noun::Cell(Cell {
                                                                                                                                              h: c.h.clone(),
                                                                                                                                              t: c.t.clone(),
                                                                                                                                          }),
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl PartialEq for Noun {
                                                                                                                                  fn eq(&self, other: &Self) -> bool {
                                                                                                                                      if let (Noun::Atom(lh), Noun::Atom(rh)) = (&*self, &*other) {
                                                                                                                                          lh == rh
                                                                                                                                      } else if let (Noun::Cell(lh), Noun::Cell(rh)) = (&*self, &*other) {
                                                                                                                                          lh == rh
                                                                                                                                      } else {
                                                                                                                                          false
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl fmt::Display for Noun {
                                                                                                                                  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                                                                                                                                      match self {
                                                                                                                                          Noun::Atom(a) => {
                                                                                                                                              write!(f, "{}", a.0)
                                                                                                                                          }
                                                                                                                                          Noun::Cell(ref c) => {
                                                                                                                                              write!(f, "[{} {}]", c.h, c.t)
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Noun {
                                                                                                                                  fn from_loobean(loob: Loobean) -> Self {
                                                                                                                                      match loob {
                                                                                                                                          Loobean::Yes => Noun::Atom(Atom(0)),
                                                                                                                                          Loobean::No => Noun::Atom(Atom(1)),
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  fn into_box(self) -> Box<Self> {
                                                                                                                                      Box::new(self)
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              #[derive(Clone, Debug, PartialEq)]
                                                                                                                              struct Atom(u64);
                                                                                                                              
                                                                                                                              #[derive(Debug)]
                                                                                                                              pub struct Cell {
                                                                                                                                  h: Box<Noun>,
                                                                                                                                  t: Box<Noun>,
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Clone for Cell {
                                                                                                                                  fn clone(&self) -> Self {
                                                                                                                                      Cell {
                                                                                                                                          h: self.h.clone(),
                                                                                                                                          t: self.t.clone(),
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl PartialEq for Cell {
                                                                                                                                  fn eq(&self, other: &Self) -> bool {
                                                                                                                                      if let (Noun::Atom(lh_h), Noun::Atom(rh_h)) = (&*self.h, &*other.h) {
                                                                                                                                          lh_h == rh_h && *self.t == *other.t
                                                                                                                                      } else if let (Noun::Cell(lh_h), Noun::Cell(rh_h)) = (&*self.h, &*other.h) {
                                                                                                                                          Self::eq(lh_h, rh_h) && *self.t == *other.t
                                                                                                                                      } else {
                                                                                                                                          false
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              #[derive(Debug, PartialEq)]
                                                                                                                              enum Loobean {
                                                                                                                                  Yes,
                                                                                                                                  No,
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Loobean {
                                                                                                                                  fn from_boolean(b: bool) -> Self {
                                                                                                                                      if b {
                                                                                                                                          Loobean::Yes
                                                                                                                                      } else {
                                                                                                                                          Loobean::No
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              #[derive(Debug)]
                                                                                                                              struct Error {
                                                                                                                                  msg: String,
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl fmt::Display for Error {
                                                                                                                                  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                                                                                                                                      write!(f, "{}", self.msg)
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl error::Error for Error {}
                                                                                                                              
                                                                                                                              trait Wut {
                                                                                                                                  fn wut(&self) -> Loobean;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Wut for Atom {
                                                                                                                                  fn wut(&self) -> Loobean {
                                                                                                                                      Loobean::No
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Wut for Cell {
                                                                                                                                  fn wut(&self) -> Loobean {
                                                                                                                                      Loobean::Yes
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              trait Lus {
                                                                                                                                  fn lus(self) -> Atom;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Lus for Atom {
                                                                                                                                  fn lus(self) -> Atom {
                                                                                                                                      Atom(1 + self.0)
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              trait Tis {
                                                                                                                                  fn tis(&self) -> Loobean;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Tis for Cell {
                                                                                                                                  fn tis(&self) -> Loobean {
                                                                                                                                      Loobean::from_boolean(self.h == self.t)
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              trait Fas {
                                                                                                                                  fn fas(self) -> Result<Noun, Error>;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Fas for Cell {
                                                                                                                                  fn fas(self) -> Result<Noun, Error> {
                                                                                                                                      let mut s = self;
                                                                                                                                      loop {
                                                                                                                                          match *s.h {
                                                                                                                                              Noun::Atom(Atom(0)) => {
                                                                                                                                                  break Err(Error {
                                                                                                                                                      msg: "/[0 a] cannot be evaluated".to_string(),
                                                                                                                                                  })
                                                                                                                                              }
                                                                                                                                              Noun::Atom(Atom(1)) => break Ok(*s.t),
                                                                                                                                              Noun::Atom(Atom(2)) => {
                                                                                                                                                  break {
                                                                                                                                                      if let Noun::Cell(t) = *s.t {
                                                                                                                                                          Ok(*t.h)
                                                                                                                                                      } else {
                                                                                                                                                          Err(Error {
                                                                                                                                                              msg: "/[2 a] cannot be evaluated when a is an atom".to_string(),
                                                                                                                                                          })
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                              Noun::Atom(Atom(3)) => {
                                                                                                                                                  break {
                                                                                                                                                      if let Noun::Cell(t) = *s.t {
                                                                                                                                                          Ok(*t.t)
                                                                                                                                                      } else {
                                                                                                                                                          Err(Error {
                                                                                                                                                              msg: "/[3 a] cannot be evaluated when a is an atom".to_string(),
                                                                                                                                                          })
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                              Noun::Atom(Atom(n)) => {
                                                                                                                                                  s = Cell {
                                                                                                                                                      h: Noun::Atom(Atom(2 + n % 2)).into_box(),
                                                                                                                                                      t: Cell {
                                                                                                                                                          h: Noun::Atom(Atom(n / 2)).into_box(),
                                                                                                                                                          t: s.t,
                                                                                                                                                      }
                                                                                                                                                      .fas()?
                                                                                                                                                      .into_box(),
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                              Noun::Cell(_) => {
                                                                                                                                                  break Err(Error {
                                                                                                                                                      msg: "/[a b] cannot be evaluated when a is a cell".to_string(),
                                                                                                                                                  })
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              trait Hax {
                                                                                                                                  fn hax(self) -> Result<Noun, Error>;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Hax for Cell {
                                                                                                                                  fn hax(self) -> Result<Noun, Error> {
                                                                                                                                      let mut s = self;
                                                                                                                                      loop {
                                                                                                                                          if let (Noun::Atom(h), Noun::Cell(t)) = (*s.h, *s.t) {
                                                                                                                                              match h {
                                                                                                                                                  Atom(0) => {
                                                                                                                                                      break Err(Error {
                                                                                                                                                          msg: "#[0 a b] cannot be evaluated".to_string(),
                                                                                                                                                      })
                                                                                                                                                  }
                                                                                                                                                  Atom(1) => break Ok(*t.h),
                                                                                                                                                  Atom(n) if 0 == n % 2 => {
                                                                                                                                                      s = Cell {
                                                                                                                                                          h: Noun::Atom(Atom(n / 2)).into_box(),
                                                                                                                                                          t: Noun::Cell(Cell {
                                                                                                                                                              h: Noun::Cell(Cell {
                                                                                                                                                                  h: t.h,
                                                                                                                                                                  t: Cell {
                                                                                                                                                                      h: Noun::Atom(Atom(n + 1)).into_box(),
                                                                                                                                                                      t: t.t.clone(),
                                                                                                                                                                  }
                                                                                                                                                                  .fas()?
                                                                                                                                                                  .into_box(),
                                                                                                                                                              })
                                                                                                                                                              .into_box(),
                                                                                                                                                              t: t.t,
                                                                                                                                                          })
                                                                                                                                                          .into_box(),
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Atom(n) => {
                                                                                                                                                      s = Cell {
                                                                                                                                                          h: Noun::Atom(Atom(n / 2)).into_box(),
                                                                                                                                                          t: Noun::Cell(Cell {
                                                                                                                                                              h: Noun::Cell(Cell {
                                                                                                                                                                  h: Cell {
                                                                                                                                                                      h: Noun::Atom(Atom(n - 1)).into_box(),
                                                                                                                                                                      t: t.t.clone(),
                                                                                                                                                                  }
                                                                                                                                                                  .fas()?
                                                                                                                                                                  .into_box(),
                                                                                                                                                                  t: t.h,
                                                                                                                                                              })
                                                                                                                                                              .into_box(),
                                                                                                                                                              t: t.t,
                                                                                                                                                          })
                                                                                                                                                          .into_box(),
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                          } else {
                                                                                                                                              break Err(Error {
                                                                                                                                                  msg: "#[a b] cannot be evaluated when a is cell and/or b is an atom"
                                                                                                                                                      .to_string(),
                                                                                                                                              });
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              trait Tar {
                                                                                                                                  fn tar(self) -> Result<Noun, Error>;
                                                                                                                              }
                                                                                                                              
                                                                                                                              impl Tar for Cell {
                                                                                                                                  fn tar(self) -> Result<Noun, Error> {
                                                                                                                                      let mut s = self;
                                                                                                                                      loop {
                                                                                                                                          if let Noun::Cell(t) = *s.t {
                                                                                                                                              match *t.h {
                                                                                                                                                  Noun::Atom(Atom(0)) => break Cell { h: t.t, t: s.h }.fas(),
                                                                                                                                                  Noun::Atom(Atom(1)) => break Ok(*t.t),
                                                                                                                                                  Noun::Atom(Atom(2)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          s = Cell {
                                                                                                                                                              h: Cell {
                                                                                                                                                                  h: s.h.clone(),
                                                                                                                                                                  t: tt.h,
                                                                                                                                                              }
                                                                                                                                                              .tar()?
                                                                                                                                                              .into_box(),
                                                                                                                                                              t: Cell { h: s.h, t: tt.t }.tar()?.into_box(),
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 2 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(3)) => {
                                                                                                                                                      break {
                                                                                                                                                          match (Cell { h: s.h, t: t.t }.tar()?) {
                                                                                                                                                              Noun::Atom(a) => Ok(Noun::from_loobean(a.wut())),
                                                                                                                                                              Noun::Cell(c) => Ok(Noun::from_loobean(c.wut())),
                                                                                                                                                          }
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(4)) => {
                                                                                                                                                      break {
                                                                                                                                                          if let Noun::Atom(a) = (Cell { h: s.h, t: t.t }.tar()?) {
                                                                                                                                                              Ok(Noun::Atom(a.lus()))
                                                                                                                                                          } else {
                                                                                                                                                              Err(Error {
                                                                                                                                                                  msg: "Cannot apply the + operator to a cell".to_string(),
                                                                                                                                                              })
                                                                                                                                                          }
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(5)) => {
                                                                                                                                                      break {
                                                                                                                                                          if let Noun::Cell(tt) = *t.t {
                                                                                                                                                              Ok(Noun::from_loobean(
                                                                                                                                                                  Cell {
                                                                                                                                                                      h: Cell {
                                                                                                                                                                          h: s.h.clone(),
                                                                                                                                                                          t: tt.h,
                                                                                                                                                                      }
                                                                                                                                                                      .tar()?
                                                                                                                                                                      .into_box(),
                                                                                                                                                                      t: Cell { h: s.h, t: tt.t }.tar()?.into_box(),
                                                                                                                                                                  }
                                                                                                                                                                  .tis(),
                                                                                                                                                              ))
                                                                                                                                                          } else {
                                                                                                                                                              Err(Error {
                                                                                                                                                                  msg: "*[a 5 b] cannot be evaluated when b is an atom"
                                                                                                                                                                      .to_string(),
                                                                                                                                                              })
                                                                                                                                                          }
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(6)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          if let Noun::Cell(ttt) = *tt.t {
                                                                                                                                                              s = Cell {
                                                                                                                                                                  h: s.h.clone(),
                                                                                                                                                                  t: Cell {
                                                                                                                                                                      h: Noun::Cell(Cell { h: ttt.h, t: ttt.t }).into_box(),
                                                                                                                                                                      t: Noun::Cell(Cell {
                                                                                                                                                                          h: Noun::Atom(Atom(0)).into_box(),
                                                                                                                                                                          t: Cell {
                                                                                                                                                                              h: Noun::Cell(Cell {
                                                                                                                                                                                  h: Noun::Atom(Atom(2)).into_box(),
                                                                                                                                                                                  t: Noun::Atom(Atom(3)).into_box(),
                                                                                                                                                                              })
                                                                                                                                                                              .into_box(),
                                                                                                                                                                              t: Noun::Cell(Cell {
                                                                                                                                                                                  h: Noun::Atom(Atom(0)).into_box(),
                                                                                                                                                                                  t: Cell {
                                                                                                                                                                                      h: s.h,
                                                                                                                                                                                      t: Noun::Cell(Cell {
                                                                                                                                                                                          h: Noun::Atom(Atom(4)).into_box(),
                                                                                                                                                                                          t: Noun::Cell(Cell {
                                                                                                                                                                                              h: Noun::Atom(Atom(4)).into_box(),
                                                                                                                                                                                              t: tt.h,
                                                                                                                                                                                          })
                                                                                                                                                                                          .into_box(),
                                                                                                                                                                                      })
                                                                                                                                                                                      .into_box(),
                                                                                                                                                                                  }
                                                                                                                                                                                  .tar()?
                                                                                                                                                                                  .into_box(),
                                                                                                                                                                              })
                                                                                                                                                                              .into_box(),
                                                                                                                                                                          }
                                                                                                                                                                          .tar()?
                                                                                                                                                                          .into_box(),
                                                                                                                                                                      })
                                                                                                                                                                      .into_box(),
                                                                                                                                                                  }
                                                                                                                                                                  .tar()?
                                                                                                                                                                  .into_box(),
                                                                                                                                                              }
                                                                                                                                                          } else {
                                                                                                                                                              break Err(Error {
                                                                                                                                                                  msg: "*[a 6 b c] cannot be evaluated when c is an atom"
                                                                                                                                                                      .to_string(),
                                                                                                                                                              });
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 6 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(7)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          s = Cell {
                                                                                                                                                              h: Cell { h: s.h, t: tt.h }.tar()?.into_box(),
                                                                                                                                                              t: tt.t,
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 7 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(8)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          s = Cell {
                                                                                                                                                              h: Noun::Cell(Cell {
                                                                                                                                                                  h: Cell {
                                                                                                                                                                      h: s.h.clone(),
                                                                                                                                                                      t: tt.h,
                                                                                                                                                                  }
                                                                                                                                                                  .tar()?
                                                                                                                                                                  .into_box(),
                                                                                                                                                                  t: s.h,
                                                                                                                                                              })
                                                                                                                                                              .into_box(),
                                                                                                                                                              t: tt.t,
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 8 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(9)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          s = Cell {
                                                                                                                                                              h: Cell { h: s.h, t: tt.t }.tar()?.into_box(),
                                                                                                                                                              t: Noun::Cell(Cell {
                                                                                                                                                                  h: Noun::Atom(Atom(2)).into_box(),
                                                                                                                                                                  t: Noun::Cell(Cell {
                                                                                                                                                                      h: Noun::Cell(Cell {
                                                                                                                                                                          h: Noun::Atom(Atom(0)).into_box(),
                                                                                                                                                                          t: Noun::Atom(Atom(1)).into_box(),
                                                                                                                                                                      })
                                                                                                                                                                      .into_box(),
                                                                                                                                                                      t: Noun::Cell(Cell {
                                                                                                                                                                          h: Noun::Atom(Atom(0)).into_box(),
                                                                                                                                                                          t: tt.h,
                                                                                                                                                                      })
                                                                                                                                                                      .into_box(),
                                                                                                                                                                  })
                                                                                                                                                                  .into_box(),
                                                                                                                                                              })
                                                                                                                                                              .into_box(),
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 9 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(10)) => {
                                                                                                                                                      break if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          if let Noun::Cell(tth) = *tt.h {
                                                                                                                                                              Cell {
                                                                                                                                                                  h: tth.h,
                                                                                                                                                                  t: Noun::Cell(Cell {
                                                                                                                                                                      h: Cell {
                                                                                                                                                                          h: s.h.clone(),
                                                                                                                                                                          t: tth.t,
                                                                                                                                                                      }
                                                                                                                                                                      .tar()?
                                                                                                                                                                      .into_box(),
                                                                                                                                                                      t: Cell { h: s.h, t: tt.t }.tar()?.into_box(),
                                                                                                                                                                  })
                                                                                                                                                                  .into_box(),
                                                                                                                                                              }
                                                                                                                                                              .hax()
                                                                                                                                                          } else {
                                                                                                                                                              Err(Error {
                                                                                                                                                                  msg: "*[a 10 b c] cannot be evaluated when b is an atom"
                                                                                                                                                                      .to_string(),
                                                                                                                                                              })
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          Err(Error {
                                                                                                                                                              msg: "*[a 10 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          })
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(11)) => {
                                                                                                                                                      if let Noun::Cell(tt) = *t.t {
                                                                                                                                                          match *tt.h {
                                                                                                                                                              Noun::Atom(_) => break Cell { h: s.h, t: tt.t }.tar(),
                                                                                                                                                              Noun::Cell(c) => {
                                                                                                                                                                  s = Cell {
                                                                                                                                                                      h: Noun::Cell(Cell {
                                                                                                                                                                          h: Cell {
                                                                                                                                                                              h: s.h.clone(),
                                                                                                                                                                              t: c.t,
                                                                                                                                                                          }
                                                                                                                                                                          .tar()?
                                                                                                                                                                          .into_box(),
                                                                                                                                                                          t: Cell { h: s.h, t: tt.t }.tar()?.into_box(),
                                                                                                                                                                      })
                                                                                                                                                                      .into_box(),
                                                                                                                                                                      t: Noun::Cell(Cell {
                                                                                                                                                                          h: Noun::Atom(Atom(0)).into_box(),
                                                                                                                                                                          t: Noun::Atom(Atom(3)).into_box(),
                                                                                                                                                                      })
                                                                                                                                                                      .into_box(),
                                                                                                                                                                  }
                                                                                                                                                              }
                                                                                                                                                          }
                                                                                                                                                      } else {
                                                                                                                                                          break Err(Error {
                                                                                                                                                              msg: "*[a 11 b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                                          });
                                                                                                                                                      }
                                                                                                                                                  }
                                                                                                                                                  Noun::Atom(Atom(_)) => {
                                                                                                                                                      break Err(Error {
                                                                                                                                                          msg: "unsupported opcode".to_string(),
                                                                                                                                                      })
                                                                                                                                                  }
                                                                                                                                                  Noun::Cell(th) => {
                                                                                                                                                      break Ok(Noun::Cell(Cell {
                                                                                                                                                          h: Cell {
                                                                                                                                                              h: s.h.clone(),
                                                                                                                                                              t: Noun::Cell(th).into_box(),
                                                                                                                                                          }
                                                                                                                                                          .tar()?
                                                                                                                                                          .into_box(),
                                                                                                                                                          t: Cell { h: s.h, t: t.t }.tar()?.into_box(),
                                                                                                                                                      }))
                                                                                                                                                  }
                                                                                                                                              }
                                                                                                                                          } else {
                                                                                                                                              break Err(Error {
                                                                                                                                                  msg: "*[a b] cannot be evaluated when b is an atom".to_string(),
                                                                                                                                              });
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              

                                                                                                                              Scala

                                                                                                                              From Steve Randy Waldman:

                                                                                                                              package object nnnock {
                                                                                                                              
                                                                                                                                sealed trait Noun;
                                                                                                                                case class Atom( value : Int ) extends Noun;
                                                                                                                                case class Cell( head : Noun, tail : Noun ) extends Noun;
                                                                                                                                implicit def toAtom( value : Int ) : Atom = Atom( value );
                                                                                                                                implicit def toInt( atom : Atom ) : Int = atom.value;
                                                                                                                              
                                                                                                                                def nock( a : Noun ) : Noun = *(a)
                                                                                                                              
                                                                                                                              
                                                                                                                                object Cell {
                                                                                                                                  private def apply( nl : List[Noun] ) : Cell = {
                                                                                                                                    nl match {
                                                                                                                                case a :: b :: Nil => Cell(a, b);
                                                                                                                                case a :: b :: c :: Nil => Cell(a, Cell(b, c));
                                                                                                                                case a :: b :: c :: tail => Cell(a, this.apply( b :: c :: tail ) );
                                                                                                                                    }
                                                                                                                                  }
                                                                                                                                  def apply(a : Noun, b : Noun, tail : Noun*) : Cell = apply( a :: b :: tail.toList );
                                                                                                                                }
                                                                                                                              
                                                                                                                                def ?( noun : Noun ) : Noun = noun match {
                                                                                                                                  case _ : Cell => 0;
                                                                                                                                  case _ : Atom => 1;
                                                                                                                                }
                                                                                                                              
                                                                                                                                @tailrec def plus( noun : Noun ) : Noun = noun match {
                                                                                                                                  case a : Atom => 1 + a;
                                                                                                                                  case c : Cell => plus( c ); //intentional endless spin
                                                                                                                                }
                                                                                                                              
                                                                                                                                def heq( noun : Noun ) : Atom = noun match {
                                                                                                                                  case Cell( a : Atom, b : Atom ) => if ( a == b ) 0 else 1;
                                                                                                                                  case Cell( a : Cell, b : Atom ) => 1;
                                                                                                                                  case Cell( a : Atom, b : Cell ) => 1;
                                                                                                                                  case Cell( a : Cell, b : Cell ) => if ((heq( Cell( a.head, b.head ) ) | heq( Cell( a.tail, b.tail ) )) == 0) 0 else 1;
                                                                                                                                  case a : Atom => heq( a ); //intentional endless spin
                                                                                                                                }
                                                                                                                              
                                                                                                                                def /( noun : Noun ) : Noun = noun match {
                                                                                                                                  case Cell(Atom(1), a) => a;
                                                                                                                                  case Cell(Atom(2), Cell(a, b)) => a;
                                                                                                                                  case Cell(Atom(3), Cell(a, b)) => b;
                                                                                                                                  case Cell(Atom(value), b ) => {
                                                                                                                                    val a = value / 2;
                                                                                                                                    val num = if ( value % a == 0 ) 2 else 3;
                                                                                                                                    /(Cell(num, /(Cell(a, b))));
                                                                                                                                  }
                                                                                                                                  case a => /( a ); //intentional endless spin
                                                                                                                                }
                                                                                                                              
                                                                                                                              
                                                                                                                                  def *( noun : Noun ) : Noun = noun match {
                                                                                                                                    case Cell( a, Cell(Cell(b, c), d) ) => Cell( *(Cell(a,b,c)), *(Cell(a,d)) );
                                                                                                                                    case Cell( a, Cell(Atom(value), tail) ) => {
                                                                                                                                      (value, tail) match {
                                                                                                                                  case (0, b) => /( Cell(b, a) );
                                                                                                                                  case (1, b) => b;
                                                                                                                                  case (2, Cell(b, c)) => *( Cell( *( Cell(a,b) ), *( Cell(a,c) ) ) );
                                                                                                                                  case (3, b) => ?( *( Cell(a,b) ) );
                                                                                                                                  case (4, b) => plus( *( Cell(a,b) ) );
                                                                                                                                  case (5, b) => heq( *( Cell(a,b) ) );
                                                                                                                                  case (6, Cell(b, Cell(c, d))) => *( Cell(a,2,Cell(0,1),2,Cell(1,c,d),Cell(1,0),2,Cell(1,2,3),Cell(1,0),4,4,b) ); //wtf?
                                                                                                                                  case (7, Cell(b, c)) => *( Cell(a,2,b,1,c) );
                                                                                                                                  case (8, Cell(b, c)) => *( Cell(a,7,Cell(Cell(7,Cell(0,1),b),0,1),c) ); //wtf2
                                                                                                                                  case (9, Cell(b, c)) => *( Cell(a,7,c,2,Cell(0,1),0,b) );
                                                                                                                                  case (10, Cell(Cell(b,c),d)) => *( Cell(a,8,c,7,Cell(0,3),d) );
                                                                                                                                  case (10, Cell(b, c)) => *( Cell(a,c) );
                                                                                                                                  case _ => *( noun ); //intentional endless spin
                                                                                                                                      }
                                                                                                                                    }
                                                                                                                                    case a => *( a ); //intentional endless spin
                                                                                                                                  }
                                                                                                                                }
                                                                                                                              

                                                                                                                              Scheme

                                                                                                                              From Kohányi Róbert:

                                                                                                                              (import (rnrs (6)))
                                                                                                                              
                                                                                                                              (define (i a) a)
                                                                                                                              
                                                                                                                              (define (n a r)
                                                                                                                                (cond
                                                                                                                                  ((list? a)
                                                                                                                                   (let ((l (length a)))
                                                                                                                                     (cond
                                                                                                                                       ((equal? l 0) (raise 1))
                                                                                                                                       ((equal? l 1) (r (car a)))
                                                                                                                                       (else
                                                                                                                                         (let ((t (cond
                                                                                                                                                    ((equal? l 2) (cadr a))
                                                                                                                                                    (else (cdr a)))))
                                                                                                                                           (n (car a)
                                                                                                                                              (lambda (p) (n t
                                                                                                                                                             (lambda (q) (r (cons p q)))))))))))
                                                                                                                                  ((fixnum? a) (r a))
                                                                                                                                  (else (raise 2))))
                                                                                                                              
                                                                                                                              (define (wut a)
                                                                                                                                (cond
                                                                                                                                  ((fixnum? a) 1)
                                                                                                                                  (else 0)))
                                                                                                                              
                                                                                                                              (define (lus a)
                                                                                                                                (cond
                                                                                                                                  ((equal? (wut a) 0) (raise 3))
                                                                                                                                  (else (+ 1 a))))
                                                                                                                              
                                                                                                                              (define (tis a)
                                                                                                                                (cond
                                                                                                                                  ((equal? (wut a) 1) (raise 4))
                                                                                                                                  ((equal? (car a) (cdr a)) 0)
                                                                                                                                  (else 1)))
                                                                                                                              
                                                                                                                              (define (fas a r)
                                                                                                                                (cond
                                                                                                                                  ((equal? (wut a) 1) (raise 5))
                                                                                                                                  (else
                                                                                                                                    (let ((h (car a))
                                                                                                                                        (t (cdr a)))
                                                                                                                                    (cond
                                                                                                                                      ((not (fixnum? h)) (raise 6))
                                                                                                                                      ((equal? h 0) (raise 7))
                                                                                                                                      ((equal? h 1) (r t))
                                                                                                                                      ((fixnum? t) (raise 8))
                                                                                                                                      ((equal? h 2) (r (car t)))
                                                                                                                                      ((equal? h 3) (r (cdr t)))
                                                                                                                                      (else
                                                                                                                                          (fas (cons (div h 2) t)
                                                                                                                                               (lambda (p) (fas (cons (+ 2 (mod h 2)) p)
                                                                                                                                                                (lambda (q) (r q)))))))))))
                                                                                                                              
                                                                                                                              (define (tar a r)
                                                                                                                                (cond
                                                                                                                                  ((equal? (wut a) 1) (raise 9))
                                                                                                                                  (else
                                                                                                                                    (let ((s (car a))
                                                                                                                                          (f (cdr a)))
                                                                                                                                      (cond
                                                                                                                                        ((equal? (wut f) 1) (raise 10))
                                                                                                                                        (else
                                                                                                                                          (let ((o (car f))
                                                                                                                                                (v (cdr f)))
                                                                                                                                            (cond
                                                                                                                                              ((equal? (wut o) 0) (tar (cons s o)
                                                                                                                                                                       (lambda (p) (tar (cons s v)
                                                                                                                                                                                        (lambda (q) (r (cons p q)))))))
                                                                                                                                              ((equal? o 0) (r (fas (cons v s) i)))
                                                                                                                                              ((equal? o 1) (r v))
                                                                                                                                              ((equal? o 3) (tar (cons s v)
                                                                                                                                                                 (lambda (p) (r (wut p)))))
                                                                                                                                              ((equal? o 4) (tar (cons s v)
                                                                                                                                                                 (lambda (p) (r (lus p)))))
                                                                                                                                              ((equal? o 5) (tar (cons s v)
                                                                                                                                                                 (lambda (p) (r (tis p)))))
                                                                                                                                              ((equal? (wut v) 1) (raise 11))
                                                                                                                                              (else
                                                                                                                                                (let ((x (car v))
                                                                                                                                                      (y (cdr v)))
                                                                                                                                                  (cond
                                                                                                                                                    ((equal? o 2) (tar (cons s x)
                                                                                                                                                                       (lambda (p) (tar (cons s y)
                                                                                                                                                                                        (lambda (q) (tar (cons p q)
                                                                                                                                                                                                         (lambda (u) (r u))))))))
                                                                                                                                                    ((equal? o 7) (tar (n (list (list s) 2 (list x) 1 (list y)) i)
                                                                                                                                                                       (lambda (p) (r p))))
                                                                                                                                                    ((equal? o 8) (tar (n (list (list s) 7 (list (list 7 (list 0 1) (list x)) 0 1) (list y)) i)
                                                                                                                                                                       (lambda (p) (r p))))
                                                                                                                                                    ((equal? o 9) (tar (n (list (list s) 7 (list y) 2 (list 0 1) 0 (list x)) i)
                                                                                                                                                                       (lambda (p) (r p))))
                                                                                                                                                    ((equal? o 10) (cond
                                                                                                                                                                     ((equal? (wut x) 1) (tar (cons s y)
                                                                                                                                                                                              (lambda (p) (r p))))
                                                                                                                                                                     (else (tar (n (list (list s) 8 (list (cdr x)) 7 (list 0 3) (list y)) i)
                                                                                                                                                                                (lambda (p) (r p))))))
                                                                                                                                                    ((equal? (wut y) 1) (raise 12))
                                                                                                                                                    ((equal? o 6) (tar (n (list
                                                                                                                                                                            (list s)
                                                                                                                                                                            2
                                                                                                                                                                            (list 0 1)
                                                                                                                                                                            2
                                                                                                                                                                            (list 1 (list (car y)) (list (cdr y)))
                                                                                                                                                                            (list 1 0)
                                                                                                                                                                            2
                                                                                                                                                                            (list 1 2 3)
                                                                                                                                                                            (list 1 0)
                                                                                                                                                                            4
                                                                                                                                                                            4
                                                                                                                                                                            (list x))
                                                                                                                                                                          i)
                                                                                                                                                                       (lambda (p) (r p))))
                                                                                                                                                    (else (raise 13)))))))))))))
                                                                                                                              

                                                                                                                              Swift

                                                                                                                              import Foundation
                                                                                                                              //  1   ::  A noun is an atom or a cell.
                                                                                                                              //  2   ::  An atom is a natural number.
                                                                                                                              //  3   ::  A cell is an ordered pair of nouns.
                                                                                                                              //  4
                                                                                                                              //  5   ::  nock(a)             *a
                                                                                                                              //  6   ::  [a b c]             [a [b c]]
                                                                                                                              //  7
                                                                                                                              //  8   ::  ?[a b]              0
                                                                                                                              //  9   ::  ?a                  1
                                                                                                                              // 10   ::  +[a b]              +[a b]
                                                                                                                              // 11   ::  +a                  1 + a
                                                                                                                              // 12   ::  =[a a]              0
                                                                                                                              // 13   ::  =[a b]              1
                                                                                                                              // 14   ::  =a                  =a
                                                                                                                              // 15
                                                                                                                              // 16   ::  /[1 a]              a
                                                                                                                              // 17   ::  /[2 a b]            a
                                                                                                                              // 18   ::  /[3 a b]            b
                                                                                                                              // 19   ::  /[(a + a) b]        /[2 /[a b]]
                                                                                                                              // 20   ::  /[(a + a + 1) b]    /[3 /[a b]]
                                                                                                                              // 21   ::  /a                  /a
                                                                                                                              // 22
                                                                                                                              // 23   ::  *[a [b c] d]        [*[a b c] *[a d]]
                                                                                                                              // 24
                                                                                                                              // 25   ::  *[a 0 b]            /[b a]
                                                                                                                              // 26   ::  *[a 1 b]            b
                                                                                                                              // 27   ::  *[a 2 b c]          *[*[a b] *[a c]]
                                                                                                                              // 28   ::  *[a 3 b]            ?*[a b]
                                                                                                                              // 29   ::  *[a 4 b]            +*[a b]
                                                                                                                              // 30   ::  *[a 5 b]            =*[a b]
                                                                                                                              // 31
                                                                                                                              // 32   ::  *[a 6 b c d]        *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
                                                                                                                              // 33   ::  *[a 7 b c]          *[a 2 b 1 c]
                                                                                                                              // 34   ::  *[a 8 b c]          *[a 7 [[7 [0 1] b] 0 1] c]
                                                                                                                              // 35   ::  *[a 9 b c]          *[a 7 c 2 [0 1] 0 b]
                                                                                                                              // 36   ::  *[a 10 [b c] d]     *[a 8 c 7 [0 3] d]
                                                                                                                              // 37   ::  *[a 10 b c]         *[a c]
                                                                                                                              // 38
                                                                                                                              // 39   ::  *a                  *a
                                                                                                                              
                                                                                                                              //  1   ::  A noun is an atom or a cell.
                                                                                                                              public indirect enum Noun: IntegerLiteralConvertible, ArrayLiteralConvertible, Equatable, Hashable, CustomStringConvertible
                                                                                                                              {
                                                                                                                                  //  2   ::  An atom is a natural number.
                                                                                                                                  public typealias ATOM = UIntMax
                                                                                                                              
                                                                                                                                  case Atom(ATOM)
                                                                                                                                  //  3   ::  A cell is an ordered pair of nouns.
                                                                                                                                  case Cell(Noun, Noun)
                                                                                                                                  case Invalid
                                                                                                                              
                                                                                                                                  public static var YES: Noun { return .Atom(0) }
                                                                                                                                  public static var NO: Noun  { return .Atom(1) }
                                                                                                                              
                                                                                                                                  public init(_ noun: Noun) { self = noun }
                                                                                                                              
                                                                                                                                  //  6   ::  [a b c]          [a [b c]]
                                                                                                                                  public init(_ nouns: [Noun]) {
                                                                                                                                      self = .Invalid
                                                                                                                                      if nouns.count > 0 {
                                                                                                                                          var reverse = nouns.reverse().generate()
                                                                                                                                          self = reverse.next()!
                                                                                                                                          while let n = reverse.next() {
                                                                                                                                              self = .Cell(n, self)
                                                                                                                                          }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  // protocol IntegerLiteralConvertible
                                                                                                                                  public typealias IntegerLiteralType = ATOM
                                                                                                                                  public init(integerLiteral value: IntegerLiteralType) {
                                                                                                                                      self = .Atom(value)
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  // protocol ArrayLiteralConvertible
                                                                                                                                  public typealias Element = Noun
                                                                                                                                  public init(arrayLiteral elements: Element...) {
                                                                                                                                      self = Noun(elements)
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  // Array subscript
                                                                                                                                  public subscript(axis: ATOM) -> Noun {
                                                                                                                                      return fas(.Cell(.Atom(axis), self))
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  // protocol Hashable
                                                                                                                                  public var hashValue: Int {
                                                                                                                                      //return self.description.hashValue
                                                                                                                                      switch self {
                                                                                                                                      case let .Atom(a):
                                                                                                                                          return a.hashValue
                                                                                                                                      case let .Cell(a, b):
                                                                                                                                          return (5381 + 31 &* a.hashValue) &+ b.hashValue
                                                                                                                                      default:
                                                                                                                                          abort()
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  // protocol CustomStringConvertible
                                                                                                                                  public var description: String {
                                                                                                                                      return describe()
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  private func describe(depth: Int = 0) -> String {
                                                                                                                                      var sub = ""
                                                                                                                                      let next = depth+1
                                                                                                                                      switch self {
                                                                                                                                      case .Invalid:
                                                                                                                                          return "[%INVALID%]"
                                                                                                                                      case let .Atom(atom):
                                                                                                                                          return "\(atom)"
                                                                                                                                      case let .Cell(.Cell(a, b), c):
                                                                                                                                          sub =  "[\(a.describe(next)) \(b.describe(next))] \(c.describe(next))"
                                                                                                                                      case let .Cell(a, b):
                                                                                                                                          sub = "\(a.describe(next)) \(b.describe(next))"
                                                                                                                                      }
                                                                                                                                      return depth == 0 ? "[\(sub)]" : sub
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              // protocol Equatable
                                                                                                                              public func == (left: Noun, right: Noun) -> Bool
                                                                                                                              {
                                                                                                                                  switch (left, right) {
                                                                                                                                  case let (.Atom(lhs), .Atom(rhs)):          return lhs == rhs
                                                                                                                                  case let (.Cell(lp, lq), .Cell(rp, rq)):    return lp == rp && lq == rq
                                                                                                                                  case (.Invalid, .Invalid):                  return true
                                                                                                                                  default:                                    return false
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func wut(noun: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  switch noun {
                                                                                                                                      //  8   ::  ?[a b]           0
                                                                                                                                  case .Cell:
                                                                                                                                      return Noun.YES
                                                                                                                                  case .Atom:
                                                                                                                                      //  9   ::  ?a               1
                                                                                                                                      return Noun.NO
                                                                                                                                  default:
                                                                                                                                      //return wut(noun)
                                                                                                                                      abort()
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func lus(noun: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  if case let .Atom(a) = noun {
                                                                                                                                      // 11   ::  +a               1 + a
                                                                                                                                      return .Atom(1+a)
                                                                                                                                  }
                                                                                                                                  // 10   ::  +[a b]           +[a b]
                                                                                                                                  //return lus(noun)
                                                                                                                                  abort()
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func tis(noun: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  if case let .Cell(a, b) = noun {
                                                                                                                                      // 12   ::  =[a a]           0
                                                                                                                                      // 13   ::  =[a b]           1
                                                                                                                                      return (a == b) ? Noun.YES : Noun.NO
                                                                                                                                  }
                                                                                                                                  // 14   ::  =a               =a
                                                                                                                                  //return tis(noun)
                                                                                                                                  abort()
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func fas(noun: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  switch noun {
                                                                                                                                      // 16   ::  /[1 a]           a
                                                                                                                                  case let .Cell(1, a):
                                                                                                                                      return a
                                                                                                                                      // 17   ::  /[2 a b]         a
                                                                                                                                  case let .Cell(2, .Cell(a, _)):
                                                                                                                                      return a
                                                                                                                                      // 18   ::  /[3 a b]         b
                                                                                                                                  case let .Cell(3, .Cell(_, b)):
                                                                                                                                      return b
                                                                                                                                      // 19   ::  /[(a + a) b]        /[2 /[a b]]
                                                                                                                                      // 20   ::  /[(a + a + 1) b]    /[3 /[a b]]
                                                                                                                                  case let .Cell(.Atom(axis), tree):
                                                                                                                                      let inner = Noun.Atom(axis / 2)
                                                                                                                                      let outer = Noun.Atom(2 + (axis % 2))
                                                                                                                                      return fas(.Cell(outer, fas(.Cell(inner, tree))))
                                                                                                                                  default:
                                                                                                                                      // 21   ::  /a                  /a
                                                                                                                                      //return fas(noun)
                                                                                                                                      abort()
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func tar(noun: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  switch noun {
                                                                                                                                  case let .Cell(a, formula):
                                                                                                                                      switch formula {
                                                                                                                                          // 23   ::  *[a [b c] d]     [*[a b c] *[a d]]
                                                                                                                                      case let .Cell(.Cell(b, c), d):
                                                                                                                                          return .Cell(tar([a, b, c]), tar([a, d]))
                                                                                                                              
                                                                                                                                          // 25   ::  *[a 0 b]         /[b a]
                                                                                                                                      case let .Cell(0, b):
                                                                                                                                          return fas([b, a])
                                                                                                                              
                                                                                                                                          // 26   ::  *[a 1 b]         b
                                                                                                                                      case let .Cell(1, b):
                                                                                                                                          return b
                                                                                                                              
                                                                                                                                          // 27   ::  *[a 2 b c]       *[*[a b] *[a c]]
                                                                                                                                      case let .Cell(2, .Cell(b, c)):
                                                                                                                                          return tar([tar([a, b]), tar([a, c])])
                                                                                                                              
                                                                                                                                          // 28   ::  *[a 3 b]         ?*[a b]
                                                                                                                                      case let .Cell(3, b):
                                                                                                                                          return wut(tar([a, b]))
                                                                                                                              
                                                                                                                                          // 29   ::  *[a 4 b]         +*[a b]
                                                                                                                                      case let .Cell(4, b):
                                                                                                                                          return lus(tar([a, b]))
                                                                                                                              
                                                                                                                                          // 30   ::  *[a 5 b]         =*[a b]
                                                                                                                                      case let .Cell(5, b):
                                                                                                                                          return tis(tar([a, b]))
                                                                                                                              
                                                                                                                                          // 32   ::  *[a 6 b c d]     *[a 2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]
                                                                                                                                      case let .Cell(6, .Cell(b, .Cell(c, d))):
                                                                                                                                          return tar([a, 2, [0, 1], 2, [1, c, d], [1, 0], 2, [1, 2, 3], [1, 0], 4, 4, b])
                                                                                                                              
                                                                                                                                          // 33   ::  *[a 7 b c]       *[a 2 b 1 c]
                                                                                                                                      case let .Cell(7, .Cell(b, c)):
                                                                                                                                          return tar([a, 2, b, 1, c])
                                                                                                                              
                                                                                                                                          // 34   ::  *[a 8 b c]       *[a 7 [[7 [0 1] b] 0 1] c]
                                                                                                                                      case let .Cell(8, .Cell(b, c)):
                                                                                                                                          return tar([a, 7, [[7, [0, 1], b], 0, 1], c])
                                                                                                                              
                                                                                                                                          // 35   ::  *[a 9 b c]       *[a 7 c 2 [0 1] 0 b]
                                                                                                                                      case let .Cell(9, .Cell(b, c)):
                                                                                                                                          return tar([a, 7, c, 2, [0, 1], 0, b])
                                                                                                                              
                                                                                                                                          // 36   ::  *[a 10 [b c] d]  *[a 8 c 7 [0 3] d]
                                                                                                                                      case let .Cell(10, .Cell(.Cell(_, c), d)):
                                                                                                                                          return tar([a, 8, c, 7, [0, 3], d])
                                                                                                                              
                                                                                                                                          // 37   ::  *[a 10 b c]      *[a c]
                                                                                                                                      case let .Cell(10, .Cell(_, c)):
                                                                                                                                          return tar([a, c]);
                                                                                                                              
                                                                                                                                      default:
                                                                                                                                          //return tar(noun)
                                                                                                                                          abort()
                                                                                                                                      }
                                                                                                                                  default:
                                                                                                                                      //return tar(noun)
                                                                                                                                      abort()
                                                                                                                                  }
                                                                                                                              }
                                                                                                                              
                                                                                                                              
                                                                                                                              public var nock_functions = Dictionary<Noun, Noun -> Noun>()
                                                                                                                              
                                                                                                                              public func dao(formula: Noun) -> Noun->Noun
                                                                                                                              {
                                                                                                                                  if let cached = nock_functions[formula] {
                                                                                                                                      return cached
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  let compiler = { () -> Noun -> Noun in
                                                                                                                                      switch formula {
                                                                                                                                      case let .Cell(.Cell(b, c), d):     // Distribution
                                                                                                                                          let (p, q) = (dao(.Cell(b, c)), dao(d))
                                                                                                                                          return { a in .Cell(p(a), q(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(0, b):               // Axis
                                                                                                                                          return { a in fas(.Cell(b, a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(1, b):               // Just
                                                                                                                                          return { _ in b }
                                                                                                                              
                                                                                                                                      case let .Cell(2, .Cell(b, c)):     // Fire
                                                                                                                                          let (f, g) = (dao(b), dao(c))
                                                                                                                                          return { a in dao(g(a))(f(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(3, b):               // Depth
                                                                                                                                          let f = dao(b)
                                                                                                                                          return { a in wut(f(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(4, b):               // Bump
                                                                                                                                          let f = dao(b)
                                                                                                                                          return { a in lus(f(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(5, b):               // Same
                                                                                                                                          let f = dao(b)
                                                                                                                                          return { a in tis(f(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(6, .Cell(b, .Cell(c, d))): // If
                                                                                                                                          let (p, q, r) = (dao(b), dao(c), dao(d))
                                                                                                                                          return { a in
                                                                                                                                              switch p(a) {
                                                                                                                                              case Noun.self.YES:
                                                                                                                                                  return q(a)
                                                                                                                                              case Noun.self.NO:
                                                                                                                                                  return r(a)
                                                                                                                                              default:
                                                                                                                                                  return tar(.Cell(a, formula))
                                                                                                                                              }
                                                                                                                                          }
                                                                                                                              
                                                                                                                                      case let .Cell(7, .Cell(b, c)):     // Compose
                                                                                                                                          let (f, g) = (dao(b), dao(c))
                                                                                                                                          return { a in g(f(a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(8, .Cell(b, c)):     // Push
                                                                                                                                          let (f, g) = (dao(b), dao(c))
                                                                                                                                          return { a in g(.Cell(f(a), a)) }
                                                                                                                              
                                                                                                                                      case let .Cell(9, .Cell(b, c)):     // Call
                                                                                                                                          let f = dao(c)
                                                                                                                                          return { a in
                                                                                                                                              let core = f(a)
                                                                                                                                              let arm = dao(fas(.Cell(b, core)))
                                                                                                                                              return arm(core)
                                                                                                                                          }
                                                                                                                              
                                                                                                                                      case let .Cell(10, .Cell(.Cell(_, c), d)): // Hint
                                                                                                                                          let ignore = dao(c)
                                                                                                                                          let f = dao(d)
                                                                                                                                          return { a in ignore(a); return f(a) }
                                                                                                                              
                                                                                                                                      case let .Cell(10, .Cell(_, c)):    // Hint
                                                                                                                                          let f = dao(c)
                                                                                                                                          return { a in f(a) }
                                                                                                                              
                                                                                                                                      default:
                                                                                                                                          return { a in tar(.Cell(a, formula)) }
                                                                                                                                      }
                                                                                                                                  }
                                                                                                                              
                                                                                                                                  let r = compiler()
                                                                                                                                  nock_functions[formula] = r
                                                                                                                                  return r
                                                                                                                              }
                                                                                                                              
                                                                                                                              public func nock(n: Noun) -> Noun
                                                                                                                              {
                                                                                                                                  if case let .Cell(a, b) = n {
                                                                                                                                      let f = dao(b)
                                                                                                                                      return f(a)
                                                                                                                                  }
                                                                                                                                  return nock(n)
                                                                                                                              }
                                                                                                                              

                                                                                                                              <-

                                                                                                                              Example

                                                                                                                              Edit this page on GitHub