for 0.91
IN: ui.freetype
: dpi 120 ;
for git version
USE: namespaces
USE: ui.freetype
120 dpi set-global
IN: ui.freetype
: dpi 120 ;
USE: namespaces
USE: ui.freetype
120 dpi set-global
I was thinking about how to let users mix up prefix, infix, and postfix syntax.
For example, + (+ 1 2) 3, 1 + 2 + 3, and 1 2 + 3 + would all be grammatical.
Using a stack and a queue, it might be possible:
Basically, it is stack based evaluation (postfix) with look ahead to give users illusion of prefix or infix.
1 + 2 + 3, for example, would be evaluated as follows:
Queue: 1 + 2 + 3
Stack:
--
Queue: + 2 + 3
Stack: 1
--
Queue: + 3
Stack: 3
--
Queue:
Stack: 6
I name the language Staque and here is prototype:
> module Main where
Import stuff for parser.
> import qualified Text.ParserCombinators.Parsec as P
> import Text.ParserCombinators.Parsec ( (<|>) )
Import stuff for printing.
> import qualified Text.PrettyPrint.HughesPJ as PP
Import stuff for repl.
> import System.IO ( stdout, hFlush )
Let's define values for the language.
> data Val = Int Integer
> | Ident String
> | Expr [Val]
Let Val to be showable.
> ppVal (Ident s) = PP.text s
> ppVal (Int i) = PP.integer i
> ppVal (Expr xs) = PP.parens (PP.hsep $ map ppVal xs)
> instance Show Val where show = PP.render . ppVal
Let's write a parser. Expression is just a list of tokens separated by whitespaces.
> parseExpr = do
> toks <- P.sepEndBy parseToken ws
> return $ Expr toks
> ws = P.skipMany1 P.space
Expression can be parenthesized.
> parseParenExpr = do
> lparen
> e <- P.sepEndBy parseToken ws
> rparen
> return $ Expr e
> where
> lparen = P.char '(' >> P.spaces
> rparen = P.spaces >> P.char ')'
A token can be an integer literal, an identifier, or a parenthesized expression.
> parseToken = do
> P.try parseParenExpr
> <|> P.try parseInt
> <|> P.try parseIdent
Let's parse integer literal. An integer literal can start with -.
> parseInt = do
> sign <- P.string "-" <|> return ""
> val <- nat
> return $ Int (read $ sign ++ val)
> nat = P.many1 P.digit
Let's parse identifier. Identifier can be operator or name.
> parseIdent = do
> ident <- parseOp <|> parseName
> return $ Ident ident
> where
> parseOp = parseHeadBody opChar opChar
> parseName = parseHeadBody nameChar nameChar
> parseHeadBody hChar bChar = do
> h <- hChar
> b <- P.many bChar
> return (h : b)
> opChar = P.oneOf ":!#$%&*+./<=>?@\\^|-~"
> nameChar = P.alphaNum <|> P.oneOf "_-'"
Now, onto actual evaluation.
Let's define stack and implement push and pop:
> type Stack = [Val]
> push v s = v : s
> pop (x:xs) = (x, xs)
Here is queue. We only consume a queue. Never push element to the queue.
> type Queue = [Val]
> front (x:xs) = (x, xs)
Evaluation function. Finally!
> eval :: Stack -> Queue -> Val
When the queue is empty, evaluation is done. Make sure the stack has only 1 element and return the element as the result of evaluation.
> eval s [] | length s == 1 = (fst . pop) s
When the queue contains an expression, evaluate the expression.
> eval s [Expr q] = eval s q
Now, the queue's front is an identifier. Let's look it up and call the function bound to the identifier. Also, we make sure the rest of the queue is evaluated with the updated stack.
> eval s (Ident fname : args) = let
> (s', q) = funcall fname s args
> in
> eval s' q
The queue's front is not an identifier. Assume it's a literal and push it to the stack and evaluate the rest of the queue.
> eval s (x : xs) = let
> s' = push x s
> in
> eval s' xs
Funcall just looks up a function. If found, it calls the function with stack and queue. The called function returns updated (Stack, Queue).
> funcall fname s q = case lookup fname primitives of
> Nothing -> error $ fname ++ " not defined"
> Just f -> f s q
Funcall looks up this map.
> primitives = [
> ("+", binNumOp (+))
> , ("-", binNumOp (-))
> , ("/", binNumOp div)
> , ("*", binNumOp (*))
> ]
Before we define a function that uses stack and queue to evaluate binary numeric operations, let's define helper functions.
To unpack and pack integers from and to Val.
> fromVal (Int a) = a
> toVal a = Int a
To evaluate values popped from stack or queue. If the popped value is an expression, evaluate the expression using a new stack. Otherwise, just return the popped value.
> evalVal val = case val of
> Expr q -> eval [] q
> otherwise -> val
Now, onto evaluation of binary numeric operation.
First, stack has 2 elements. So, both arguments to the binary operation can be popped from the stack. The arguments popped are evaluated because they can be nested expressions. Then push the result of operation to the stack and return it with queue.
> binNumOp op s q | length s >= 2 = let
> (b, s') = pop s
> (a, s'') = pop s'
> a' = evalVal a
> b' = evalVal b
> result = toVal $ fromVal a' `op` fromVal b'
> in
> (push result s'', q)
When stack has only 1 element, we should pop from the queue, too.
> binNumOp op s q | length s >= 1 = let
> (a, s') = pop s
> (b, q') = front q
> a' = evalVal a
> b' = evalVal b
> result = toVal $ fromVal a' `op` fromVal b'
> in
> (push result s', q')
Stack is empty. So, pop 2 arguments from the queue.
> binNumOp op s q = let
> (a, q') = front q
> (b, q'') = front q'
> a' = evalVal a
> b' = evalVal b
> result = toVal $ fromVal a' `op` fromVal b'
> in
> (push result s, q'')
Now, let's make a repl.
> repl = do
> input <- prompt "staque> "
> if input == ":q"
> then putStrLn "bye"
> else do
> putStrLn $ evaluate input
> repl
> where
> prompt p = do
> putStr p
> hFlush stdout
> getLine
Actual evaluate function that transforms user input to string.
> evaluate s = case P.parse parseExpr "staque" s of
> Left err -> show err
> Right (Expr q) -> show $ eval [] q
Finally, main function.
> main = repl
Let's run it!
$ runhaskell staque.lhs
staque> 1 + 2
3
staque> + 1 2
3
staque> 1 2 +
3
staque> 1 + 2 + ((1 - -2) * 3) 3 / (+ 1 2) *
12
staque> :q
bye
For exercises:
I bought SOE. And here is GLFW PKGBUILD for Archlinux:
pkgname=glfw2hs
pkgver=0.3
pkgrel=1
pkgdesc="A Haskell module for GLFW OpenGL framework. It provides an alternative to GLUT for OpenGL based Haskell programs."
url="http://haskell.org/haskellwiki/GLFW"
license=('GPL')
depends=('gcc' 'ghc' 'xorg-server')
arch=('i686')
source=("GLFW-$pkgver.tar.gz")
install=('glfw2hs.install')
md5sums=('c1cefce0573dd0237031fc3d28b4514d')
build() {
cd "$startdir/src/GLFW-$pkgver"
runhaskell Setup.hs configure --ghc --prefix=/usr
runhaskell Setup.hs build || return 1
runhaskell Setup.hs register --gen-script
runhaskell Setup.hs unregister --gen-script
install -D -m744 register.sh "$startdir/pkg/usr/share/haskell/$pkgname/register.sh"
install -m744 unregister.sh "$startdir/pkg/usr/share/haskell/$pkgname/unregister.sh"
runhaskell Setup.hs copy --destdir="$startdir/pkg"
}
This is glfw2hs.install:
HS_DIR=/usr/share/haskell/glfw2hs
post_install() {
${HS_DIR}/register.sh
echo "GLFW registered"
}
pre_upgrade() {
${HS_DIR}/unregister.sh
}
post_upgrade() {
${HS_DIR}/register.sh
}
pre_remove() {
${HS_DIR}/unregister.sh
}
op=$1
shift
$op $*
I bought [SOE](http://haskell.org/soe/).
And here is GLFW PKGBUILD for Archlinux:
pkgname=glfw2hs
pkgver=0.3
pkgrel=1
pkgdesc="A Haskell module for GLFW OpenGL framework. It provides an alternative to GLUT for OpenGL based Haskell programs."
url="http://haskell.org/haskellwiki/GLFW"
license=('GPL')
depends=('gcc' 'ghc' 'xorg-server')
arch=('i686')
source=("GLFW-$pkgver.tar.gz")
install=('glfw2hs.install')
md5sums=('c1cefce0573dd0237031fc3d28b4514d')
build() {
cd "$startdir/src/GLFW-$pkgver"
runhaskell Setup.hs configure --ghc --prefix=/usr
runhaskell Setup.hs build || return 1
runhaskell Setup.hs register --gen-script
runhaskell Setup.hs unregister --gen-script
install -D -m744 register.sh "$startdir/pkg/usr/share/haskell/$pkgname/register.sh"
install -m744 unregister.sh "$startdir/pkg/usr/share/haskell/$pkgname/unregister.sh"
runhaskell Setup.hs copy --destdir="$startdir/pkg"
}
This is glfw2hs.install:
HS_DIR=/usr/share/haskell/glfw2hs
post_install() {
${HS_DIR}/register.sh
echo "GLFW registered"
}
pre_upgrade() {
${HS_DIR}/unregister.sh
}
post_upgrade() {
${HS_DIR}/register.sh
}
pre_remove() {
${HS_DIR}/unregister.sh
}
op=$1
shift
$op $*
Ok. Writing a song in 30 minutes.
| G/B | Bm7 | C/B | Bm7 |
a b a b a e a d a g f# g a d a d d b
C | Bm/C | Cm | Eb F
f# d d g f# g a b c g a b c g d
Sam, be joyous again. Your precious days are near here across the nations. Rejoice now. Hail through the night. Get some sleep now. Wipe your tears away.
Epoch time starts from 1970. Given a date in YYYY-MM-DD, list all dates that evaluates to 1970. For example, 2005-11-24 = 1970.
In python:
[(yyyy,mm,dd)
for dd in range(1,31)
for mm in range(1,12)
for yyyy in range(1970+1+1,1970+12+31)
if time.localtime(time.mktime((yyyy,mm,dd,0,0,0,0,0,0)))[:3] == (yyyy,mm,dd)
and yyyy-mm-dd == 1970]
So, 1970+12+31 = 2013
Type system jargons:
----------------------+------------------------------+-----------------------
Yes | | No
----------------------+------------------------------+-----------------------
Manifest | | Latent
| explicit type declaration |
`int a = 1` | | `a = 1`
| |
----------------------+------------------------------+-----------------------
Static | | Dynamic
| AST node has type |
| (note AST is built during |
| compilation) |
`a + 2` | | `a + 2`
already is Int | | is evaluated to 3
during compilation | | during runtime
| | and gets type Int
| |
----------------------+------------------------------+-----------------------
Weak | | Strong
| type coercion |
`print 2` | | `print (String)2`
Int is automatically | | Int is explicitly
coerced to String | | converted to String
| |
----------------------+------------------------------+-----------------------
Nominative | | Structural
| type compatibility decleared |
| explicitly |
`class C extends B` | | `class C { x, y }`
C is compatible to B | | `class B { x }`
because it is | | C is compatible
explicitly | | to B because it
declared to extend B | | has similar
| | structure
----------------------+------------------------------+-----------------------
Type system jargons:
----------------------+------------------------------+-----------------------
Yes | | No
----------------------+------------------------------+-----------------------
Manifest | | Latent
| explicit type declaration |
`int a = 1` | | `a = 1`
| |
----------------------+------------------------------+-----------------------
Static | | Dynamic
| AST node has type |
| (note AST is built during |
| compilation) |
`a + 2` | | `a + 2`
already is Int | | is evaluated to 3
during compilation | | during runtime
| | and gets type Int
| |
----------------------+------------------------------+-----------------------
Weak | | Strong
| type coercion |
`print 2` | | `print (String)2`
Int is automatically | | Int is explicitly
coerced to String | | converted to String
| |
----------------------+------------------------------+-----------------------
Nominative | | Structural
| type compatibility decleared |
| explicitly |
`class C extends B` | | `class C { x, y }`
C is compatible to B | | `class B { x }`
because it is | | C is compatible
explicitly | | to B because it
declared to extend B | | has similar
| | structure
----------------------+------------------------------+-----------------------
Romans 9:11-12 The Lord said this to show that he makes his own choices and that it wasn't because of anything either of them had done.
Romans 9:14-16 Are we saying that God is unfair? Certainly not! The Lord told Moses that he has pity and mercy on anyone he wants to. Everything then depends on God's mercy and not on what people want or do.
Romans 9:18 Everything depends on what God decides to do, and he can either have pity on people or make them stubborn.
Romans 9:19-20 Someone may ask, "How can God blame us, if he makes us behave in the way he wants us to?" But, my friend, I ask, "Who do you think you are to question God? Does the clay have the right to ask the potter why he shaped it the way he did?
So, there seem to be fate and destiny, and they govern my life. I hope my fate is not to be stubborn, but to receive pity from above.
1
12 4
11 24 9
10 22 36 16
9 20 33 48 25
8 18 30 44 60 36
7 16 27 40 55 72 49
6 14 24 36 50 66 84 64
5 12 21 32 45 60 77 96 81
4 10 18 28 40 54 70 88 108 100
3 8 15 24 35 48 63 80 99 120 121
2 6 12 20 30 42 56 72 90 110 132 144
combination(n+1, 2) numbers in an
(equilateral) triangle
For example, when n = 12, generate combination(13, 2)
= 13!/(2!11!) = 78 numbers.
n = 1, combination(2,2) = 1.
1
n = 2, combination(3,2) = 3.
1
2 4
n = 3, combination(4,2) = 6.
1
3 4
2 6 9
n = 4, combination(5,2) = 10.
1
4 4
3 8 9
2 6 12 16
See the pattern?
1^2
4 2^2
3 4*2 3^2
2 3*2 4*3 4^2
Rotating the triangle counter clockwise might reveal something:
1^2 2^2 3^3 4^2
4*1 4*2 4*3
3*1 3*2
2*1
In general, for input n,
1^2 2^2 ..................................... n^2
n*1 n*2 ....................... n*(n-1)
(n-1)*1 (n-1)*2 ... (n-1)*(n-1-1)
.....................
2
Let's implement it in Haskell, an obscure language.
module Main where
First, declare a module.
import qualified System.IO as Sys
import qualified IO
Then, import stuff needed.
main :: IO ()
main = do
IO.hSetBuffering IO.stdout IO.NoBuffering
Sys.putStr "Enter n (>=1): "
num <- Sys.getLine
let n :: Integer
n = read num
print' $ consul n (*)
main function definition. It disables stdout buffering
so that the prompt is displayed immediately without waiting for the
buffer to be flushed (probably flushed when new line is printed).
Then it reads an integer from user and prints the triangle.
consul :: (Integral a) => a -> (a -> a -> a) -> [[a]]
consul n func = (map reverse . diagonals) $ consul' n func
consul just calls consul' then applies
diagonals to the output. Then, it applies
reverse on each element of the output.
consul' :: Integral a => a -> (a -> a -> a) -> [[a]]
consul' n func = [map (^2) [1..n]]
++ [zipWith func (repeat x) [1..x-1] | x <- [n,n-1..2]]
consul' constructs the upside down triangle described
above. The triangle is expressed as a list of list of integers.
[[1^2, 2^2, ....................................., n^2]
, [n*1, n*2, ......................., n*(n-1)]
, [(n-1)*1, (n-1)*2, ..., (n-1)*(n-1-1)]
, .....................
, [2]]
diagonals :: [[a]] -> [[a]]
diagonals [[]] = [[]]
diagonals ([]:ls) = diagonals ls
diagonals ((x:xs):ls) = [x] : zipWith (:) xs (diagonals ls)
diagonals takes elements along the diagonal (NE to
SW). Essentially, it rotates the upside triangle clockwise and
flips. Since the output triangle is flipped, reverse
should be applied for each element list to re-flip the triangle.
print' :: (Show a) => [[a]] -> IO ()
print' [] = return ()
print' (l:ls) = do
putStrLn $ replicate (length ls) ' ' ++ show l
print' ls
print' prints the list of list of integers as a
triangle by appending spaces in front of each row.
[Consul, the Educated Monkey](http://rbandrews.livejournal.com/128578.html).
1
12 4
11 24 9
10 22 36 16
9 20 33 48 25
8 18 30 44 60 36
7 16 27 40 55 72 49
6 14 24 36 50 66 84 64
5 12 21 32 45 60 77 96 81
4 10 18 28 40 54 70 88 108 100
3 8 15 24 35 48 63 80 99 120 121
2 6 12 20 30 42 56 72 90 110 132 144
- Input: n
- Output: `combination(n+1, 2)` numbers in an _(equilateral)_ triangle
For example, when n = 12, generate `combination(13, 2)` = 13!/(2!11!) = 78
numbers.
n = 1, `combination(2,2) = 1`.
1
n = 2, `combination(3,2) = 3`.
1
2 4
n = 3, `combination(4,2) = 6`.
1
3 4
2 6 9
n = 4, `combination(5,2) = 10`.
1
4 4
3 8 9
2 6 12 16
See the pattern?
1^2
4 2^2
3 4*2 3^2
2 3*2 4*3 4^2
Rotating the triangle counter clockwise might reveal something:
1^2 2^2 3^3 4^2
4*1 4*2 4*3
3*1 3*2
2*1
In general, for input `n`,
1^2 2^2 ..................................... n^2
n*1 n*2 ....................... n*(n-1)
(n-1)*1 (n-1)*2 ... (n-1)*(n-1-1)
.....................
2
Let's implement it in Haskell, an obscure language.
> module Main where
First, declare a module.
> import qualified System.IO as Sys
> import qualified IO
Then, import stuff needed.
> main :: IO ()
> main = do
> IO.hSetBuffering IO.stdout IO.NoBuffering
> Sys.putStr "Enter n (>=1): "
> num <- Sys.getLine
> let n :: Integer
> n = read num
> print' $ consul n (*)
`main` function definition.
It disables stdout buffering so that the prompt is displayed
immediately without waiting for the buffer to be flushed
(probably flushed when new line is printed).
Then it reads an integer from user and prints the triangle.
> consul :: (Integral a) => a -> (a -> a -> a) -> [[a]]
> consul n func = (map reverse . diagonals) $ consul' n func
`consul` just calls `consul'` then applies `diagonals` to the output.
Then, it applies `reverse` on each element of the output.
> consul' :: Integral a => a -> (a -> a -> a) -> [[a]]
> consul' n func = [map (^2) [1..n]]
> ++ [zipWith func (repeat x) [1..x-1] | x <- [n,n-1..2]]
`consul'` constructs the upside down triangle described above.
The triangle is expressed as a list of list of integers.
[[1^2, 2^2, ....................................., n^2]
, [n*1, n*2, ......................., n*(n-1)]
, [(n-1)*1, (n-1)*2, ..., (n-1)*(n-1-1)]
, .....................
, [2]]
> diagonals :: [[a]] -> [[a]]
> diagonals [[]] = [[]]
> diagonals ([]:ls) = diagonals ls
> diagonals ((x:xs):ls) = [x] : zipWith (:) xs (diagonals ls)
`diagonals` takes elements along the diagonal (NE to SW).
Essentially, it rotates the upside triangle clockwise and flips.
Since the output triangle is flipped, `reverse` should be applied for
each element list to re-flip the triangle.
> print' :: (Show a) => [[a]] -> IO ()
> print' [] = return ()
> print' (l:ls) = do
> putStrLn $ replicate (length ls) ' ' ++ show l
> print' ls
`print'` prints the list of list of integers as a triangle by appending
spaces in front of each row.
This is Hello.lhs. It uses
Markdown.
First, declare module name:
module Main where
Second, define main function:
main :: IO ()
main is of type IO ().
main = do
putStrLn "Hello, World!"
That's the entire hello world in Haskell. To compile this,
ghc Hello.lhs
To convert this into HTML,
sed -e 's/^> / /' Hello.lhs | pandoc
KTHXBYE.
This is `Hello.lhs`.
It uses [Markdown](http://daringfireball.net/projects/markdown/).
First, declare module name:
> module Main where
Second, define `main` function:
> main :: IO ()
`main` is of type `IO ()`.
> main = do
> putStrLn "Hello, World!"
That's the entire hello world in Haskell.
To compile this,
ghc Hello.lhs
To convert this into HTML,
sed -e 's/^> / /' Hello.lhs | pandoc
KTHXBYE.