Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

finite state machines in scheme

Name: Anonymous 2013-03-01 3:25

yea. anyone got sum kool examplez?

Name: Anonymous 2013-03-01 6:48

let's see what u guyz got

letsee ya portfolio n stuff

finite state machines mate

in skeem

Name: Anonymous 2013-03-01 8:42

I'm more interested in infinite state machines.  You got any of those?

Name: Anonymous 2013-03-01 8:57

>>3
Sure
(repl)

Name: Anonymous 2013-03-01 10:43

>>1
Do your own homework.

Name: Anonymous 2013-03-01 14:59

>>1

There you go. It is made in a lisp dialect.

It is a finite state machine, which can match permutations of the regular expression you throw in it:


{-# LANGUAGE GADTs, TypeOperators, MultiParamTypeClasses, FlexibleInstances, NoMonomorphismRestriction #-}
module Data.Decider where

import           Control.Applicative
import           Control.Arrow
import           Control.Category
import           Data.Monoid hiding (Any, All)

data Expr g a where
    Any :: [Expr g a] -> Expr g a
    All :: [Expr g a] -> Expr g a
    FromTo :: Integer -> Integer -> Expr g a -> Expr g a
    One :: a -> Expr g a
    From :: Integer -> Expr g a -> Expr g a
    To :: Integer -> Expr g a -> Expr g a
        deriving Show
    {--
    Module :: Expr g a -> Expr (M :+: g) a
    Destructive :: Expr g a -> Expr (D :+: g) a
    Once :: Expr g a -> Expr (O :+: g) a
    --}

data a :+: b
data M
data D
data O

class Evaluate a b where
    match :: a -> b -> Bool

-- "[12[34]]"
simpleRule = All[
        One 1, One 2, All [
                        One 3,
                        One 4
                ]]
simpleRule2 = All [Any [All [One 1, One 2], One 3]]

toOne :: Expr g a -> Maybe a
toOne (One a) = Just a
toOne (All [x]) = toOne x
toOne (Any xs) = foldr step (Nothing) xs
        where step  x z = z <|> toOne x
toOne (FromTo 1 _ x) = toOne x
toOne (From 1 x) = toOne x
toOne (To x y) = toOne y
toOne _ = Nothing

-- | Every expression gives rise to function

equalDecider = buildDecider (==)

-- The underlying arrow is Machine a b = [a] -> ([b], Bool)
-- deltaStream = xs - ys 
--
newtype Decider a = Decider {
            runDecider :: [a] -> ([a], Bool)         
        }

instance Monoid (Decider a) where
        mempty = Decider $ \xs -> (xs, True)
        mappend (Decider f) (Decider g) = Decider $ \xs -> let (xs', b) = f xs
                                                           in case b of
                                                                True -> runDecider (Decider g) xs'
                                                                False -> (xs, b)

buildDecider :: (a -> b -> Bool) -> Expr g b -> Decider a
buildDecider f (From from p) = Decider $ \xs ->
                                      let (xs',b) = step xs 0
                                      in if b >= from
                                            then (xs', True)
                                            else (xs, False)
        where step xs n = let (xs', b) = runDecider (buildDecider f p) xs
                          in case b of
                                False -> (xs, n)
                                True ->  step xs' (n + 1)
buildDecider f (To to p) = Decider $ \xs ->
                                  let (xs',b) = step xs 0
                                  in if b <= to
                                            then (xs, True)
                                            else (xs, False)
        where step xs n = let (xs', b) = runDecider (buildDecider f p) xs
                          in case b of
                                False -> (xs, n)
                                True ->  step xs' (n + 1)
buildDecider f (FromTo from to p) = Decider $ \xs ->
                                           let (xs', b) = runDecider (buildDecider f (From from p)) xs
                                           in case b of
                                                False -> (xs, False)
                                                True -> let (_,b) = runDecider (buildDecider f (To to p)) xs
                                                        in case b of
                                                            False -> (xs, False)
                                                            True -> (xs', True)
buildDecider f (One p)  = Decider $ \xs -> member f p xs
buildDecider f (All ps) = Decider $ \xs ->
                                 let (xs', b) = step ps xs
                                 in case b of
                                        True -> (xs', b)
                                        False -> (xs, b)
        where step [] xs = (xs, True)
              step (p:ps) xs  = let (xs', b) = runDecider (buildDecider f p) xs
                                in case b of
                                        True -> step ps xs'  
                                        False -> (xs, False)
buildDecider f (Any ps) = Decider $ \xs -> step ps xs
        where step [] xs = (xs, False)
              step (p:ps) xs = let (xs', b) =  runDecider (buildDecider f p) xs 
                               in case b of
                                        True -> (xs',True)
                                        False -> step ps xs


-- The most primitive building block. This is satisfy, when you build
-- a parser. We use member, because we need to allow all permutations 
member :: (a -> b -> Bool) -> b -> [a] -> ([a],Bool)
member f x [] = ([], False)
member f x (y:xs) | f y x = (xs, True)
                  | otherwise = let (ns,t) = member f x xs
                                in (y:ns,t)

accept :: (a -> b -> Bool) -> b -> [a] -> Bool
accept f x [] = False
accept f x (y:xs) | f y x = True
                  | otherwise = accept f x xs 

-- underline machine is actually very boring. It has some flapping

newtype Machine a b = Machine {
                        runMachine :: [a] -> ([b], Bool)
                }


instance Category Machine where
        id = Machine $ \xs -> (xs, True)
(.-) a b = Machine $ \xs -> let (as, bt) = runMachine a xs
                                (bs, ct) = runMachine b as
                            in  (bs, (bt && ct))


And a parser:


optimize (All [(All xs)]) = optimize $ All (optimize <$> xs)
optimize (Any [(Any xs)]) = optimize $ Any (optimize <$> xs)
optimize (All [t]) = optimize t
optimize (Any [t]) = optimize t
optimize (Any xs) = Any (optimize <$> xs)
optimize (All xs) = All ((joinSame xs))
optimize z = z

joinSame xs = let (as,bs) = foldr splitAll ([],[]) xs
              in case as of
                    [] -> (optimize <$> bs)
                    [x] -> optimize x : (optimize <$> bs)
                    xs -> optimize <$> (optimize <$> xs) ++ (optimize <$> bs)
    where splitAll (All x) (alls,dfs) = (x ++ alls, dfs)
          splitAll x (alls, dfs) = (alls, x : dfs)

[/code]

Name: Anonymous 2013-03-01 15:01

>>6

There is no parser, I cut it out of the source.

Name: Anonymous 2013-03-01 17:32

Since when is Dead Dog a Lisp dialect?

Name: Anonymous 2013-03-01 18:45

>>8
Since the time Ahmed was selling his unreadable APLCaml language as ``in Lisp''.

Name: Anonymous 2013-03-02 0:44

>>5
I don't have any.

Name: Anonymous 2013-03-02 10:53

>>9
But Symta is really based on Lisp. It even uses lambdas to represents objects and packages, just likes SICP prescribed. Besides, Symta implemented on top of CL.

Name: Anonymous 2013-03-02 11:10

>>9
But Symta is Lisp, check the source code.

Name: Anonymous 2013-03-02 12:01

Lisp is symta.

Name: Anonymous 2013-03-02 12:51

>>11,12
You are not differentiating the language itself from the language in which it's implemented. And ``inspired by Lisp'' is what Javashit retards like to claim all the time.

Well, I'm guessing that you don't care much for compile-time guarantees and such, so knock yourself out with the closures-for-everything as long as you enjoy it. At least you don't plug your project in every thread like you did back then.

Name: Anonymous 2013-03-02 12:55

>>14
Does your Javashit have macros?

Name: Anonymous 2013-03-02 12:59

>>15
Does your ``in Lisp'' have S-Expressions?

Name: Anonymous 2013-03-02 13:04

>>16
No. It uses binary-tree instead of cons-pairs.

Name: Anonymous 2013-03-02 13:06

>>17
That's like saying "oh my son is Israeli but he doesn't observe JEWdaism and he's a gay Christian"

Name: Anonymous 2013-03-02 13:09

>>14
Javashit wasn't implemented ``in Lisp'', Symta was.

But that would be like saying sepples programs are the same as ``in C'' programs, so I understand what you're trying to say.

Still, I love Symta, Nikita, JEWS and Muslims.

Name: Anonymous 2013-03-02 13:17

>>17
I take it that you mean that rather than using cons-lists, you use trees? That's interesting, Guy Steele (IIRC) chastised the Lisp community for sticking with singly-linked lists for too long, when that kills concurrency among other things. I had always the had in mind that if I made a toy language, and decided to roll my own data structures, I'd just go with trees for everything: they are easily understood and rather predictable.

Either way, Symta ain't homoiconic, which is one of the defining features of Lisp. It's its own language, treat it with the respect a language deserves.

Name: Anonymous 2013-03-02 13:19

>>19
Javashit wasn't implemented ``in Lisp''
Actually, It was.

http://bc.tech.coop/blog/030920.html
"Mozilla's CVS tree still contains the original implementation of Javascript... written in Common Lisp. I don't have the address handy for it, but I've certainly seen it. Javascript was in that sense a Lisp-based domain-specific language with domain-suitable objects (ad-hoc prototypes and closures)."

Name: Anonymous 2013-03-02 13:20

Name: Anonymous 2013-03-02 13:24

>>20
I take it that you mean that rather than using cons-lists, you use trees?
Yes. Because I want fast indexing, catenation and insertion. Languages like Lua use hashtables, but they don't allow catenation or indexing at all.

Name: Anonymous 2013-03-02 13:25

>>23
Besides, hashtables aint purely-functional, while binary trees allow path-copying.

Name: Anonymous 2013-03-02 15:23

>>20
Symta ain't homoiconic
Symta is homoiconic, because there is a `read` function, which parses "A*B+C" into (`+` (`*` A B) C), which could be easily manipulated with expressions like <[O1 [O2 X Y] Z]=(X O2 Y) O1 Z>
That works because newest Symta has Smalltalk-like message passing and operators O1 and O2 would be passed as messages.

Name: Anonymous 2013-03-02 17:08

>>17
You do realise an S-expression is an n-ary tree, right?

Name: Anonymous 2013-03-02 18:09

>>25
But dude, the thing is that "A*B+C" is not a Symta datastructure. Your read function transforms it into a Lisp datastructure, which by virtue of existing in the same runtime, Symta code can also manipulate, but that structure is not the same as Symta's syntax, it's just the AST you built.

To make an analogy, you could write a Python parser in Python which produces its AST as a Python object and manipulate Python code that way, but that wouldn't make Python homoiconic.

This doesn't detract form Symta per-se, but it doesn't make it Lisp.

Name: Anonymous 2013-03-02 19:19



EVERYTHING IS LISP
LISP IS EVERYTHING

Name: Anonymous 2013-03-02 19:23

EVERYTHING IS NOTHING
NOTHING IS LISP
LISP IS NOTHING

Name: Anonymous 2013-03-02 20:02

JEWS ARE KIKES
KIKES ARE EVIL
KILL ALL KIKES

Name: Anonymous 2013-03-02 20:05

Why would anyone still use scheme?
Racket is where it at now.

Name: Anonymous 2013-03-02 20:50

>>31
racket is a scheme

Name: Anonymous 2013-03-02 21:57

scheme is a racket!

Name: Anonymous 2013-03-02 22:22

Name: Anonymous 2013-03-02 22:45

>>3
That's not infinite since you ultimately become limited by the contents of the memory used by your interpreter. The concept of infinity is only useful for telling other kids how strong your dad is in an argument.

Name: Anonymous 2013-03-02 22:49

>>35
what is the last natural number you retarded piece of shit?

Name: Anonymous 2013-03-02 23:00

>>36
There aren't any natural numbers since they're just an idea. Do you see numbers occurring anywhere in nature aside from in the minds of humans?

Name: Anonymous 2013-03-02 23:22

>>37
Yes. The number zero occurs when one asks how many times you will get laid.

Name: Anonymous 2013-03-02 23:35

>>38
No, but the number "one" does, you moron.

Name: Anonymous 2013-03-02 23:38

Oh, and keep in mind that it's only from your own perspective that it occurs, so it's still in a human's mind.

Name: Anonymous 2013-03-03 5:55

>>40
Secretly your dad will be watching you.

Name: Anonymous 2013-03-03 7:41

>>26
Made of cons-pairs. SEXPs allow stuff like (a b . c), created with (cons a (cons b c)). Atomic lists don't allow that.

>>27
But dude, the thing is that "A*B+C" is not a Symta datastructure.
"A*B+C" is just (`+` (`*` A B) C), like Lisp's "'s" is just (quote s)

To make an analogy, you could write a Python parser in Python which produces its AST as a Python object and manipulate Python code that way
Nope.
Python's AST would be impractically hard to manipulate.
See http://norvig.com/python-lisp.html


Python does not have macros. Python does have access to the abstract syntax tree of programs, but this is not for the faint of heart. On the plus side, the modules are easy to understand, and with five minutes and five lines of code I was able to get this:

>>> parse("2 + 2")
['eval_input', ['testlist', ['test', ['and_test', ['not_test', ['comparison',
 ['expr', ['xor_expr', ['and_expr', ['shift_expr', ['arith_expr', ['term',
  ['factor', ['power', ['atom', [2, '2']]]]], [14, '+'], ['term', ['factor',
   ['power', ['atom', [2, '2']]]]]]]]]]]]]]], [4, ''], [0, '']]

Name: Anonymous 2013-03-03 7:47

>>42
Python does have access to the abstract syntax tree of programs, but this is not for the faint of heart.
So delicate~

Name: Anonymous 2013-03-03 8:30

>>42
The point in >>26 was that you can easily construct a binary tree with S-expressions and cons cells. Contrast this statement with >>16,17

Name: Anonymous 2013-03-03 8:31

Also >>42
Nope.
Way to entirely miss the point and attack the irrelevant part of the analogy.

Name: Anonymous 2013-03-03 8:56

http://norvig.com/python-lisp.html
The two main drawbacks of Python from my point of view are (1) there is very little compile-time error analysis and type declaration, even less than Lisp, and (2) execution time is much slower than Lisp, often by a factor of 10 (sometimes by 100 and sometimes by 1). Qualitatively, Python feels about the same speed as interpreted Lisp, but very noticably slower than compiled Lisp. For this reason I wouldn't recommend Python for applications that are (or are likely to become over time) compute intensive (unless you are willing to move the speed bottlenecks into C). But my purpose is oriented towards pedagogy, not production, so this is less of an issue.

Yet mercurial happened...

Name: Anonymous 2013-03-03 10:47

>>46
Which is precisely why people prefer git over Mercurial.

Name: Anonymous 2013-03-03 23:18

>>35


ever heard of proper tail calls?

Name: Anonymous 2013-03-03 23:55

>>> parse("2 + 2")
['eval_input', ['testlist', ['test', ['and_test', ['not_test', ['comparison',
 ['expr', ['xor_expr', ['and_expr', ['shift_expr', ['arith_expr', ['term',
  ['factor', ['power', ['atom', [2, '2']]]]], [14, '+'], ['term', ['factor',
   ['power', ['atom', [2, '2']]]]]]]]]]]]]]], [4, ''], [0, '']]

Is… this as ugly as it looks?

Name: Anonymous 2013-03-04 3:48

>>49
>>> (parse "(+ 2 2)")
(+ 2 2)
>>>

Don't change these.
Name: Email:
Entire Thread Thread List