normalcalc
Jump to navigation
Jump to search
| Paradigm(s) | functional |
|---|---|
| Designed by | User:Itoh Shimon |
| Appeared in | 31 July 2024 (JST) |
| Computational class | Turing complete |
| Major implementations | Original |
| Influenced by | Unlambda Lazy K brainfuck |
| File extension(s) | .nc |
Normalcalc, designed by User:Itoh Shimon in 25-26 November 2023 (JST) and appeared in 31 July 2024 (JST), is a purely functional esoteric programming language based on combinatory logic and monadic IO.
Syntax
<program> ::= "`" <value> <value> <value> ::= "*" | "/" | "|" | "_" | "," | "." | <program>
Operators
| Operator | Description |
|---|---|
`
|
Function application operator |
*
|
Substitution function (the S combinator; takes three values and applies the result applying the first one to the third one, to the result applying the second one to the third one) |
/
|
Constant function (the K combinator; takes two values and returns the first one) |
|
|
Bind function (also called flatMap; takes a monad and a function that takes a value in that monad and returns a monad, and returns a monad) |
_
|
Return function (also called pure and unit; takes a value and returns a monad containing it) |
,
|
Input function (takes a value, discards it, and returns a monad containing an input byte) |
.
|
Output function (takes an output byte and returns a monad containing an empty tuple) |
#
|
Line comment |
Other characters are ignored.
Specifications
- Lazy evaluation (for fixed point combinators)
- Functions are curried.
- Normalcalc programs return a monad (also called procedure).
- Bytes are represented as Church numerals.
- Empty tuples are represented as identity functions (the I combinator; takes a value and returns it).
Examples
no-op
`_/
Equivalent Haskell pseudocode:
main = return const
cat (for a single character)
``|`,/.
Equivalent Haskell pseudocode:
main = (>>=) (read1byte const) write1byte
full:
-- builtin:
import System.IO
import qualified Data.ByteString as BS
read1byte :: a -> IO Integer
read1byte _ = do
eof <- isEOF
if eof
then return 256
else toInteger . BS.head <$> BS.hGet stdin 1
write1byte :: Integer -> IO ()
write1byte = BS.hPut stdout . BS.pack . (:[]) . fromIntegral
-- program:
main = (>>=) (read1byte const) write1byte
See also
Other combinatory logic languages that support IO actions: