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

Elegance of Haskell

Name: Anonymous 2016-10-23 8:03

quicksort [] = []
quicksort (x:xs) = quicksort small ++ (x : quicksort large)
where small = [y | y <- xs, y <= x]
large = [y | y <- xs, y > x]

Name: Anonymous 2016-10-23 8:05

qsort [] = []
qsort (x:xs) = qsort ys ++ x : qsort zs where (ys, zs) = partition (< x) xs

Name: Anonymous 2016-10-23 9:03

length [] = 0
length (x:xs) = 1 + length xs

Name: Anonymous 2016-10-23 10:17

import Control.Exception

import Data.Typeable

newtype Foo = Foo (() -> IO ())

{- set Foo’s TypeRep to be the same as ErrorCall’s -}

instance Typeable Foo where

typeOf _ = typeOf (undefined :: ErrorCall)

instance Show Foo where show _ = “”

instance Exception Foo

main = Control.Exception.catch (error “kaboom”) (\ (Foo f) -> f ())

Name: Anonymous 2016-10-23 10:26

{-# LANGUAGE RankNTypes, FlexibleContexts, FlexibleInstances, StandaloneDeriving, MultiParamTypeClasses, TupleSections, TypeFamilies, GADTs, DataKinds, KindSignatures, ViewPatterns, ScopedTypeVariables #-}
module RewriteSystem where

import GHC.TypeLits
import Data.Maybe
import Data.List
import Data.Monoid
import Data.String
import Control.Applicative hiding (empty)
import qualified Control.Applicative as A
import qualified Data.Vector as V
import Test.QuickCheck
import Debug.Trace
import Data.Graph.Inductive hiding (empty)
import qualified Data.Graph.Inductive as I
import Control.Monad.State
import qualified Data.Set as S
import qualified Data.HashMap.Strict as M
import Data.Hashable
import Data.GraphViz
import Data.GraphViz.Attributes.Complete
import Data.Version
import Data.Graph.Inductive.Query
import Data.Graph.Analysis.Algorithms
import Control.Parallel.Strategies
import Control.DeepSeq

data RuleState = T | I
deriving Show

data RuleTree (t :: RuleState) c where
Initial :: [c] -> RuleTree I c
Transformed :: [c] -> [RuleTree T c] -> RuleTree T c

instance NFData c => NFData (RuleTree t c) where
rnf (Initial xs) = rnf xs
rnf (Transformed xs ts) = rnf xs `seq` rnf ts

deriving instance Show c => Show (RuleTree t c)

data Rules c = Rules [([Match c], [Match c])]
data RuleType = P | M | E

instance Show c => Show (Rules c) where
show (Rules xs) = unlines $ map show' xs
where show' (x,y) = mconcat (show `fmap` x) ++ " -> " ++ mconcat (show `fmap` y)

data Match c where
Match :: c -> Match c
Positional :: Integer -> Match c

instance Eq c => Eq (Match c) where
(==) (Match p) (Match q) = p == q
(==) (Positional p) (Positional q) = p == q
(==) _ _ = False

instance NFData c => NFData (Match c) where
rnf (Match c) = rnf c `seq` ()
rnf (Positional i) = i `seq` ()

instance Show c => Show (Match c) where
show (Match c) = show c
show (Positional i) = "(" ++ show i ++ ")"

data Side = LHS | RHS

data MatchProxy (q :: RuleType) c where
MatchP :: c -> MatchProxy M c
PositionalP :: Integer -> MatchProxy P c

class AddRule a (s :: Side) (t :: RuleType) (p :: RuleType) where
(|>) :: MatchProxy t a -> RulesBuilder s (C p q) a -> RulesBuilder s (C t (C p q)) a

instance AddRule a LHS p E where
(|>) = RuleAdd

instance AddRule a LHS M M where
(|>) = RuleAdd

instance AddRule a LHS P M where
(|>) = RuleAdd

instance AddRule a LHS M P where
(|>) = RuleAdd

instance AddRule a RHS p q where
(|>) = RuleAdd

ruleSystem :: [RulesBuilder p () c] -> Rules c
ruleSystem xs = Rules $ map (\(RulePair x y) -> (toRule x, toRule y)) xs

data C (p :: RuleType) q = CProxy

data RulesBuilder (s :: Side) p c where
EndRule :: RulesBuilder s (C E ()) c
RuleAdd :: MatchProxy x c -> RulesBuilder s r c -> RulesBuilder s (C x r) c
RulePair :: RulesBuilder LHS (C x r) c -> RulesBuilder RHS t c -> RulesBuilder s () c

empty :: RulesBuilder p (C E ()) c
empty = EndRule

p :: Integer -> MatchProxy P c
p = PositionalP

c :: c -> MatchProxy M c
c = MatchP

(|->) :: RulesBuilder LHS (C x r) c -> RulesBuilder RHS t c -> RulesBuilder q () c
(|->) = RulePair

infixr 4 |->

infixr 5 |>
toRule :: RulesBuilder s p c -> [Match c]
toRule (RuleAdd x p) = case x of
MatchP c -> Match c : toRule p
PositionalP i -> Positional i : toRule p
toRule EndRule = []

type Axiom c = [c]

initialAxiom :: Axiom c -> RuleTree I c
initialAxiom = Initial

-- | Histomorphism like function to allow append to the results (Left it as it is) or replace the topmost result (make it Right)
histo :: Alternative f => (a -> f b -> Either b (f b)) -> [a] -> f b -> f b
histo f (x:xs) z = histo f xs (zipEither . bimap ((<|>z).pure) id . f x $ z)
histo _ _ z = z

zipEither :: Either a a -> a
zipEither (Left a) = a
zipEither (Right a) = a

mergeRule :: [Match c] -> [Either Integer [c]]
mergeRule (Match x:xs) = case mergeRule xs of
(Right s : xs) -> Right (x:s) : xs
ts -> Right [x] : ts
mergeRule (Positional x:xs) = Left x : mergeRule xs
mergeRule [] = []

-- | bibind for either
-- f : a -> b + d, g : c -> b + d
-- p : a -> b, q : c -> d, s : a -> d, t : c -> b
--
-- a ------- p \/ s-------------\
-- | ia |
-- \|/ \|/
-- a + c ------- f + g -----> b + d
-- /|\ /|\
-- | |
-- | ic |
-- c ------- q \/ t ------------/
--
-- f + g . ic = f + g . ia
-- p \/ s = f + g . i a
-- q \/ t = f + g . i c

-- | Bimap for either
bimap :: (a -> b) -> (c -> d) -> Either a c -> Either b d
bimap f g (Left a) = Left (f a)
bimap f g (Right c) = Right (g c)

-- | The idea is to form a template from the current string with the matches and positional parameters put into place.
-- Example:
--
-- 1 qq 2 -> 2 qq 1 and start point qq ss qq rr
-- action | rule | current template | matches
-- store pos 1 | 1 qq 2 | \1 | {}
-- match qq | qq 2 | \1 m | {{{},{qq},{ss qq rr}},{{qq,ss}, {qq}, {rr}}
-- store pos 2 | 2 | \1 m \2 | {}
--
-- Matching phase:
-- \1 m \2 <> {{{},{qq},{ss}}, {{qq, ss}, {qq}, {rr}}}
-- \1 -> {}, m -> {qq}, \2 -> {ss qq rr}
-- \1 -> {qq, ss}, m -> {qq}, \2 -> {rr}
-- Then apply the template.
-- PositionalHolder 1 {} (MatchHolder {qq} (PositionalHoler 2 {ss, qq, rr} End}
-- PositionalHolder 1 {qq, ss} (MatchHolder {qq} (PositionalHoler 2 {rr} End}
data TemplateState = Partial | Full

data Template (s :: TemplateState) c where
PositionalHolder :: Integer -> [c] -> [c] -> Template Partial c -> Template Partial c
MatchHolder :: [c] -> Template Partial c -> Template Partial c
Template :: Template Partial c -> Template Full c
EndTemplate :: Template Partial c

instance NFData c => NFData (Template x c) where
rnf (PositionalHolder i cs xs tp) = i `seq` rnf cs `seq` rnf xs `seq` rnf tp `seq` ()
rnf (MatchHolder c tp) = rnf c `seq` rnf tp `seq` ()
rnf (Template tp) = rnf tp
rnf (EndTemplate) = ()
deriving instance Show c => Show (Template s c)

replace :: (NFData a, Eq a) => a -> a -> [a] -> [a]
replace a r = parMap rdeepseq (\x -> ifp (x == a) r x)

orL :: [a] -> [a] -> [a]
orL [] xs = xs
orL xs [] = xs
orL a _ = a

transformSystem :: (NFData c, Eq c, Show c) =>
RuleTree I c -- ^ The initial axiom(s)
-> Rules c -- ^ The rules of the rewrite system
-> Maybe Integer -- ^ Maximal depth specification, Nothing means infinite.
-> RuleTree T c -- ^ A potentially infinite tree with recursively transformed axiom
transformSystem ia rules@(Rules rs) = workerp ia rs
where -- workerp :: (Eq c, Show c) => RuleTree s c -> [([Match c], [Match c])] -> Maybe Integer -> RuleTree T c
workerp (Initial ia) _ (Just 0) = Transformed ia []
workerp (Initial ia) rs depth = let tps = fmap (\(x,y) -> (,y) <$> buildMatchTemplate' x ia) rs
in Transformed ia $ (\ia -> transformSystem ia rules (pred <$> depth)) <$> (map step =<< tps)
step ((ls, tp, rs), ss) = Initial (applyTemplate ls rs tp ss)

applyTemplate :: (NFData c, Eq c, Show c) => [c] -> [c] -> Template Full c -> [Match c] -> [c]
applyTemplate ls rs (Template tp) inp = ls <> guardRights (walkTemplate tp (mergeRule inp)) <> rs

guardRights :: [Either a [b]] -> [b]
guardRights = fromMaybe [] . foldr step (Just [])
where step (Left i) (Just _) = Nothing
step (Right xs) (Just z) = Just (xs ++ z)
step _ Nothing = Nothing

walkTemplate :: (NFData c, Eq c, Show c) => Template Partial c -> [Either Integer [c]] -> [Either Integer [c]]
walkTemplate (PositionalHolder i ls rs tp) inp = walkTemplate tp ( let x = replace (Left i) (Right $ let p = ls `orL` rs in p) inp in x )
walkTemplate (MatchHolder _ tp) inp = walkTemplate tp inp
walkTemplate (EndTemplate) inp = inp

tplStrat :: NFData b => Strategy ([a],b,[a])
tplStrat = parTuple3 (evalList rseq) rdeepseq (evalList rseq)

-- | This works correctly
buildMatchTemplate' :: (NFData c, Eq c, Show c) => [Match c] -> [c] -> [([c],Template Full c, [c])]
buildMatchTemplate' (mergeRule -> ss) ds = let xs = worker ss ds in fmap (\(x,y,z) -> (x, Template y,z)) xs
where worker (s:ss) ds = case s of
Right ts -> let matches = searchString ts ds
in foldl (flip (step ss)) [] matches
Left i -> let xs = worker ss ds
in fmap (\(x,tp,y) -> ([], PositionalHolder i x y tp, [])) xs
worker [] ds = [(ds, EndTemplate, [])]
step ss (ls, m, rs) z =
let xs = worker ss rs
in fmap (\ (rest, tp, rs) -> (ls, MatchHolder m tp, rest ++ rs)) xs ++ z

ifp :: Bool -> a -> a -> a
ifp p a b | p = a
| otherwise = b

-- | Checks if we can apply a rule by finding an relevant substring
-- | and we return the rest to check if we only have a partial match
prematch :: (NFData c, Eq c) => [c] -> [c] -> Maybe ([c], [c], [c])
prematch = (listToMaybe .) . searchString

searchString :: (Eq c, NFData c) => [c] -> [c] -> [([c],[c],[c])]
searchString rs ds = cutout (V.length rs') ds' $ searchString' rs' ds'
where rs' = V.fromList rs
ds' = V.fromList ds

cutout :: (NFData c) => Int -> V.Vector c -> [(Int, Int)] -> [([c], [c], [c])]
cutout lm vs = parMap tplStrat (\(ib, ie) ->
let prefix = V.take ib vs
infixs = V.take lm $ V.drop ib vs
suffix = V.drop (ie + 1) vs
in (V.toList prefix, V.toList infixs, V.toList suffix))

-- This should be a faithful implementation of knuth search algorithm
searchString' :: (Eq c) => V.Vector c -> V.Vector c -> [(Int, Int)]
searchString' rs ds = let lrs = V.length rs
matchTable = V.toList $ V.findIndices (rs V.! 0==) ds
in join $ fmap (step lrs) matchTable
where step lrs i | i + lrs - 1 < V.length ds = ifp (foldr step' True [i .. i + lrs - 1]) (pure (i, lrs + i - 1)) []
| otherwise = []
where step' ix = ((rs V.! (ix - i) == ds V.! ix) &&)

{-- Rule tree to graph --}
type GraphState' c = (Int, M.HashMap [c] Int, M.HashMap Int (S.Set Int), Maybe Int)
type GraphState c = State (GraphState' c)

treeToDot :: (Labellable [c], Hashable c, Ord c) => RuleTree T c -> DotGraph Node
treeToDot = graphToDot dotParams . toGraph

dotParams :: Labellable [c] => GraphvizParams Node [c] String () [c]
dotParams = defaultParams { fmtNode = \ (_,l) -> [toLabel l], fmtEdge = \ (_, _, l) -> [toLabel l], isDirected = True, globalAttributes = let x = globalAttributes nonClusteredParams in EdgeAttrs [Dir Back] : x}

mapToGraph :: GraphState' c -> Gr [c] String
mapToGraph (_, ntable, etable, _) = mkGraph ((\(x,y) -> (y,x)) <$> M.toList ntable) $ worker (M.toList etable)
where worker ((k,sn):xs) = ((\x -> (k,x, "")) <$> S.toList sn) ++ worker xs
worker [] = []

toGraph :: (Hashable c, Eq c) => RuleTree T c -> Gr [c] String
toGraph tr = mapToGraph $ execState (toGraph' tr) (0 :: Int, M.empty, M.empty, Nothing)
where toGraph' :: (Hashable c, Eq c) => RuleTree T c -> GraphState c ()
toGraph' (Transformed cr trs) = do
nn <- assignNumber cr
connectEdges nn
withParentNode nn $ forM_ trs toGraph'
withParentNode :: Int -> GraphState c a -> GraphState c a
withParentNode nn m = do
(nr, ntable, etable, pnode) <- get
put (nr, ntable, etable, Just nn)
a <- m
(nr, ntable, etable, _) <- get
put (nr, ntable, etable, pnode)
return a
connectEdges :: Int -> GraphState c ()
connectEdges nn = do
(nr, ntable, etable, pnode) <- get
case pnode of
Nothing -> return ()
Just p -> case M.lookup nn etable of
Nothing -> put (nr, ntable, M.insert nn (S.singleton p) etable, pnode)
Just x -> put (nr, ntable, M.insert nn (S.insert p x) etable, pnode)
assignNumber :: (Eq c, Hashable c) => [c] -> GraphState c Int
assignNumber node = do
(nr, ntable, etable, pnode) <- get
case M.lookup node ntable of
Nothing -> put (succ nr, M.insert node nr ntable, etable, pnode) >> return nr
Just p -> return p

chunkParMap :: Int -> Strategy b -> (a -> b) -> [a] -> [b]
chunkParMap n strat f = withStrategy (parListChunk n strat) . map f

{-- Some tests --}

prop_searchStringValid = property test_searchStringValid

test_searchStringValid :: Int -> [String] -> Bool
test_searchStringValid ix xs = case searchString (show ix) (unwords (show ix : intersperse (show ix) xs)) of
[] -> False
[("", m, "")] -> m == show ix
xs -> and $ check <$> xs

where check (ls,m,rs) | m /= show ix = False
| otherwise = or ((\x -> x `isSuffixOf` ls || x `isSuffixOf` rs) <$> xs)

{-- Utility functions --}

saveAsDot:: (Hashable c, Labellable [c], Ord c) => FilePath -> RuleTree T c -> IO FilePath
saveAsDot fp tr = runGraphviz (treeToDot tr) DotOutput fp

saveAsXDot:: (Hashable c, Labellable [c], Ord c) => FilePath -> RuleTree T c -> IO FilePath
saveAsXDot fp tr = runGraphviz (treeToDot tr) (XDot (Just $ Version [1,4] [])) fp

{-- Analysis --}

transitiveClosure :: Gr c a -> Gr c String
transitiveClosure = emap (const "") . trc

toDotWith f ts = runGraphviz ( graphToDot dotParams . f . toGraph ts ) DotOutput

{-- System --}

cyclicSystem :: Rules Char
cyclicSystem = ruleSystem [
p 1 |> c 'p' |> p 2 |> c 'q' |> empty |-> c 't' |> p 1 |> p 2 |> empty,
c 't' |> c 'p' |> p 1 |> empty |-> p 1 |> p 1 |> empty,
c 'p' |> c 'p' |> empty |-> c 'p' |> c 't' |> empty,
c 'p' |> c 'p' |> empty |-> c 't' |> c 'p' |> empty,
c 'p' |> c 'p' |> empty |-> c 'q' |> empty,
p 1 |> c 'q' |> c 't' |> p 2 |> empty |-> p 1 |> c 'q' |> p 2 |> c 't' |> p 2 |> c 't' |> p 1 |> empty,
c 't' |> p 1 |> c 'q' |> empty |-> c 't' |> c 'q' |> empty,
c 't' |> c 'q' |> empty |-> c 't' |> c 'p' |> c 'p' |> empty

]

testSystem :: Rules Char
testSystem = ruleSystem [
-- c 'c' |> empty |-> c 't' |> empty,
c 't' |> p 1 |> empty |-> p 1 |> p 1 |> c 'c' |> empty,
c 'c' |> c 't' |> empty |-> c 'g' |> empty,
c 'g' |> p 1 |> c 't' |> empty |-> c 'g' |> c 'a' |> empty,
c 'a' |> p 1 |> c 'c' |> empty |-> c 't' |> p 1 |> empty,
c 't' |> c 'a' |> p 1 |> c 'a' |> c 't' |> p 2 |> empty |-> p 2 |> p 1 |> empty
]

Name: Anonymous 2016-10-23 14:21

>>5
What the fuck

Name: Anonymous 2016-10-23 14:41

>>6
Its some sort of taboo to text mixins in haskell?

Name: Anonymous 2016-10-23 16:56

splitTwo :: [a] -> ([a], [a])
splitTwo [] = ([], [])
splitTwo [x] = ([x], [])
splitTwo (x:x':xs) = (x:l, x':r)
where
(l, r) = splitTwo xs

mergeSort :: (Ord a) => [a] -> [a]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs = merge (mergeSort l) (mergeSort r)
where
(l, r) = splitTwo xs
merge xss [] = xss
merge [] yss = yss
merge xss@(x:xs) yss@(y:ys)
| x <= y = x : merge xs yss
| otherwise = y : merge xss ys


>>5
There are so many ghc extensions I can't see the entire line in browser oh god

Name: Anonymous 2016-10-23 19:13

import Data.Monoid
import Data.Foldable
import Control.Monad.Writer
import Control.Monad.State

data BT a = Leaf a | Node (BT a) (BT a)

instance Foldable BT
where
foldMap f (Leaf a) = f a
foldMap f (Node a b) = foldMap f a `mappend` foldMap f b


And now you are able to do
foldMap (Any . (==1)) $ Node (Leaf 1) (Leaf 5)

Name: Anonymous 2016-10-23 19:29

>>8

Well actually, I wanted a simple application to let the kids punch in some rewrite rules and then show, what kind of cycles it made (find the repeating pattern). Most of the code deals with a DSL, which constrain the syntax with the type system, so you cannot enter wrong rules. I could have done it at runtime, but that was ugly.

That takes a lot of extensions. At least the following:

TypeFamilies for type equality. DataKinds for creating new kinds (promoting ordinary data types to kinds). KindSignatures, otherwise DataKinds is a bit useless. And finally GADTs for the type refinement.

(And MultiParamTypeClasses, FlexibleInstances and Contexts are usually there too).

Anyway with those you can do things like:

data Side = LHS | RHS

-- The idea of GADTs is that upon type construction, you can fix a type parameter. Which is very handy.
-- Here Term takes (a :: Side), which has two types: LHS or RHS and b, which can be anything. In the types you can specialize these.

data Term (a :: Side) b where
Add :: Term RHS Integer -> Term RHS Integer -> Term RHS Integer
Var :: String -> Term RHS b -> Term LHS b
...
-- And then further in the code:

class DoSomething f where
blub :: f a -> f a -> f a

-- E.g. now I define only for RHS, thus if I encounter a LHS Term, a type error occurs.
instance DoSomething (Term RHS) where
blub :: Term RHS a -> Term RHS a -> Term RHS a

-- Without GADTs you need to hide the constructor and create smart constructors for the type.
-- Without DataKinds you need to create n newtypes for every type constructor of your datakinds. It would look like this:

newtype LHSTerm b = LHSTerm (Term b)
newtype RHSTerm b = RHSTerm (Term b)

mkVar :: String -> RHSTerm b -> LHSTerm b
mkAdd :: RHSTerm Integer -> RHSTerm Integer -> RHSTerm Integer

-- And then proceed with creating the classes DoSomething only for RHSTerm.
-- But you will still have problems. Without GADTs it makes it more difficult to create a function like eval:

eval :: Term (a :: Side) b -> Result b

Name: Anonymous 2016-10-23 19:32

But yea, it is quite hideous.

Name: Anonymous 2016-10-23 20:25

>>1

wow elegant and it runs on O(n log n) time just like normal quickshart!

Name: Anonymous 2016-10-23 21:19

>>12

Make that O(n^2) because of the crappy choice of the pivot. (The first element).

The problem with these 'elegant' implementations is, is that they aren't really solving the problem at hand, e.g. sorting the list efficiently.

Also using haskell, one would use a tree sort instead of a quicksort implemented with a hylomorphism, so the intermediate structure is only virtual.

Name: Anonymous 2016-10-23 21:31

>>13
If you have that, taking the minimum of a list by:

minimum = head . sort

Only costs you O(n) instead of O(n log(n)) thanks to laziness.

And if you make it a balanced tree, you even have a guaranteed O(nlog(n)) runtime behaviour for general sorting, but a bit of a higher constant. Not sure, if you can construct the tree lazy in that case.

Name: Anonymous 2016-10-24 1:42

Хаскелл на данный момент является лучшим языком для новых проектов. Исключительная выразительность языка и мощная система типов позволят Вам быстро писать элегантный и надежный код. Язык еще не столь распространён. пока ваши конкуренты используют устаревшие технологии на базе нетипизированных лямбла-исчислений или императивного подхода с элементами динамической типизации, вы сможете в разы поднять свою эффективность, задействовав System F - последнее достижение науки в области статической типизации. Но это еще не все. В жизни любого стартапа наступает момент, когда он превращается в продукт и сопровождению проекта привлекаются дополнительные разработчики. На этом этапе распространённость и доступность языка начинает играть решающую роль. Благодаря активной популяризации Хаскелла и функционального программирования в среде коммерческих программистов, а также поддержке этого языка со стороны лидера производства оффисных приложений и операционных систем - корпорации Майкрософт, Вы можете быть уверены, что в будущем Вам не придется переписывать свой проект на С++, как это было с печально известной разработкой Пола Грэма. Хаскелл обеспечит вам гарантии успеха и стабильности Ваших начинаний. Выберите Хаскелл сейчас и через несколько лет Вы сможете наслаждаться результатами своих трудов - успешным проектом, выполненным с учетом всех современных технологий и индустриальных стандартов. Хаскелл - Ваш проводник к успеху в мире разработки программного обеспечения. Выбирайте Хаскелл.

Name: Жив Здоров 2016-10-24 11:35

«Душка» имеет сложный метод понимания входа повествовательного предложения в русском языке. По поступлении существитльного или местоимения в роли подлежащего, модуль InStantiate начинает ожидать какой-нибудь глагол как основной носитель идеи предложения. Когда глагол придёт, программные механизмы модуля InStantiate отмечает глагол особыми параметрами лица и числа. Например, если скажете: «русские знают стихи», «Душка» отметит глагол меткой «num» (число) со значением множественного числа и меткой «dba» для категории лица со значением третьего лица. (Этимологическое примечание: английские буквы «dba» — начальные буквы английских слов «doing business as», что значит: ведущий (ведя) дела как ..., выступающий (выступая) в роли ... .) Используя метки-параметры в поисках формы третьего лица множественного числа глагола «знать», Душка в будущем сможет найти ту же форму того же глагола в процессе строения русскоязычной мысли. Если Душке нужна какая-то форма какого-то глагола и она не может найти её в памяти отмеченной метками-параметрами, тогда ИИ-ный модуль VerbPhrase (словосочетание с глаголом) призывает модуль VerbGen (generate verb, образовать глагол) создать требуемую форму данного русского глагола.

http://ai.neocities.org

Name: Anonymous 2016-10-24 11:46

Wtf Я люблю Haskell прямо сейчас

Name: Anonymous 2016-10-24 12:59

Another advantage of Haskell over Lisp, it does not depend on executing data being off(Data Execution Prevention/Write^Execute/NX bit/eXecute Disable) while Lisp (as if it were 90's self-modifying virus) builds "executable data structures". Haskell respects the data/code boundaries and security of the machine it runs on, Lisp is an open window to viral code and exploits.

Name: Anonymous 2016-10-24 13:05

>>18
Doesn't that mean that compiled Lisp executables won't run on modern Windows computers?

Name: Anonymous 2016-10-24 13:20

>>19
If they use eval or write anything into code segment(rewriting function body at runtime for example), and the policy is "DEP enabled with no exceptions" and the lisp executable isn't using JIT/VM bytecode(i.e. only compiled native code) then it will show up as error.
However the danger is not that it crashes, its that it eagerly executes data with its loose data/code boundaries.
Crashing is actually preventing the exploits.

Name: Anonymous 2016-10-25 17:24

>>18
That's actually quite rare nowadays: W^X aside, it's quite inefficient to compile things on the fly most of the time: most lisps avoid if at all possible, and bytecode compiled lisps don't even have to bother with compilation in the first pace.

But if you really want maximum efficiency in runtime generated code, that's the way to do it.

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