coder . cl » haskell http://coder.cl web developer & system programmer Sat, 03 Nov 2012 12:37:47 +0000 en hourly 1 http://wordpress.org/?v=3.4.2 a working AST generator http://coder.cl/2012/10/a-worker-ast-generator/ http://coder.cl/2012/10/a-worker-ast-generator/#comments Wed, 24 Oct 2012 20:41:42 +0000 Daniel Molina Wegener http://coder.cl/?p=2897 As you know I am trying to participate on the last challenge on the blog La Sombra de Dijkstra, where you must provide a program that compares two Fortran IV programs and must determine if both programs are equivalent. I have finished the first component, the Abstract Syntax Tree of the program. This will allow me to run the program creating an interpreter, and also will allow me to analyze the program structure — the complete Abstract Syntax Tree as graph — and make some heuristics on it.

First I want to convert that AST into Lambda Calculus functions to check if both programs are beta equivalent regarding its Lambda Calculus. I know that the program is not functional, and probably I will not find the proper representation, but I want to try it. Then I will try to reduce the graph to the lesser amount of calls, for example, removing duplicate Goto statements, trying to simplify the graph. To do that, and to use the Functional Graph Library (FGL) on the graph analysis, I must implement the Labellable instance for each node to work with each node type directly, rather than using text labels — Show instances for now.

The resulting AST for the first example, where the code can be seen as in this link, is as follows.

The resulting AST for the second example, where the code can be seen as in this link, is as follows.

The main problem is the fact that Fortran IV analyzer should be able to analyze different programs with up to 1000 lines of code. I don’t know if Parsec — the Parser Combinator library that I am using — will be capable to process that amount of code. Probably I will request one of those example files. You can find the source here.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/a-worker-ast-generator/feed/ 0
compiler flags for correctness http://coder.cl/2012/10/compiler-flags-for-correctness/ http://coder.cl/2012/10/compiler-flags-for-correctness/#comments Fri, 05 Oct 2012 10:52:29 +0000 Daniel Molina Wegener http://coder.cl/?p=2853 As I have discussed on a previous blog post, static typing helps on correctness by providing well-typed programs through type checking algorithms. Compiler warning messages and compiler error messages are not thrown as they were made by a capricious developer. Almost all of them are following a language definition, and they help if you want to build better programs. The more strict are your compiler flags, better are your programs. Using language extensions, which are not present on their standard definitions is not so cool as it seems. That depends on the language, sometimes there is very long time after certain language extensions are passed to the language definition. So, you should try to look on how can you write better code for that language without abusing of its extensions and extra features provided by the compiler.

Almost every compiler or language interpreter has warning and error flags that can help you to write better code. On my case, I use the flags “-Wall -Wextra -Wshadow -pedantic -std=c99” with gcc(1) and “-Wall -Wextra -Wshadow -pedantic -std=c++98” with g++(1). That allows me to write better source, which can be compiled by different versions of the same compiler, and that source code is easier to be migrated to other platforms, because it is not abusing of some nifty gcc(1) extensions. The same strictness is applied to other languages. I compile Haskell source code using the flags “-Wall -Werror” with ghc(1). I think that you have similar options in your compiler, and what those compiler flags on my examples are doing is pretty clear — if you have deep programming practices.

The same applies to language interpreters. I recall my Perl scripts starting with the “-W” and the “use strict” directives. So, compiler flags can help you to write better code, but sometimes compiler flags are not enough to build better programs. You can use third party tools that can help you too. Most compiler flags enabling strict checks are making your code use a better approach on its type checker and language constructs, but there are some third party tools that will allow you to check your source code for common mistakes and flaws. That is the case of static analyzers, metric tools and style checkers. Each tool will bring you a better idea about how your code can meet correctness through a type checker and similar semantic analysis. Strict language semantics will lead you to better scopes of your program goals. For example if you are working on a Python 2.X project, that will be ported to Python 3.X, you can use the “-3” flag to warn you about incompatibilities with Python 3.X. Start reviewing your compiler flags, playing a little with them, learning on how your compiler can enhance your programming practices.

Correctness can be easily reached if you can use strict semantics of your favorite programming language. For example if you are using Python as a programming language, you can use some static analyzers like pylint, pycheckers, pep8 and pyflakes, among other tools. If you can pick all those warnings thrown by that kind of tools and your compiler flags, you will be writing better code.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/compiler-flags-for-correctness/feed/ 0
base conversion tricks http://coder.cl/2012/10/base-conversion-tricks/ http://coder.cl/2012/10/base-conversion-tricks/#comments Thu, 04 Oct 2012 11:13:10 +0000 Daniel Molina Wegener http://coder.cl/?p=2847 Base conversion can be used to compress number representations, and can be used to hide the real number representation. The algorithm is well known, anyone can program that algorithm, and it is not so hard to handle. I was playing with Haskell writing that algorithm to check how effective is that algorithm to create URL shorteners. My idea is quite simple, you have an URL database ID, which is an integer number, indexed as many entries on the database, but once the database starts growing, the number can reach a length that is not so easy to remember. For example the ID 999 999 999 999 is not so easy to remember.

The basic algorithm is to have an ASCII alphabet as representation of positional numeric system symbols, and then to apply the standard base conversion algorithm using that alphabet to get the string representation of the number, so encoding and decoding algorithms in Haskell can be written as follows.


alpha :: String
alpha = "0123456789"
        ++ "abcdefghijklmnopqrstuvwxyz"
        ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        ++ "._"

alphaLength :: Integer
alphaLength = fromIntegral $ length alpha

aenc :: Integer -> String
aenc i = let fin = fromIntegral alphaLength
             encn :: Integer -> String -> String
             encn x y
                 | x == 0 = reverse y
                 | otherwise = let (n, m) = x `divMod` fin
                                   r = alpha !! fromIntegral m
                               in encn n $ y ++ [r]
         in encn i []

adec :: String -> Integer
adec i = let fin = alphaLength
             lns = fromIntegral $ length i
             decn :: String -> Integer -> Integer -> Integer
             decn (x:xs) y z = let
                 pw, el, nm :: Integer
                 pw = lns - (fromIntegral z + 1)
                 el = fromIntegral
                      $ fromJust
                      $ elemIndex x alpha
                 nm = (el * (fin ^ pw)) + fromIntegral y
                 in decn xs nm (z + 1)
             decn [] y _ = y
         in decn i 0 0

The encoding and decoding algorithms above are using a numeric base of 64, and the alphabet is case-sensitive. So, for the number 12 345 we have the string representation on numeric base 64 as “30V”. The number 999 999 999 999 has the representation as “ezkFg__” and 999 999 999 999 999 has the representation as “3znWAND__”. The trick on the base conversion on numbers with that size is made thanks to the data types used on the base conversion. The standard integer and long data types in C have up to 64 bits and probably 128 bits in some systems. Still they have a limit. With the Integer data type in Haskell there is almost no limit because they are “arbitrary-precision integers”. To use that kind of numbers on C, you must install a library like apcalc.

Also you can hide the number representation if you keep your alphabet private and you modify the positional symbols, where you can have a very different number representation of any number using this kind of base conversion, depending on your alphabet. Another option is to use bit representations, so you can extend the base alphabet to other ASCII symbols and have an extended base conversion, for example using 128 printable characters you can have a base 128 encoded number.

This encoding is very similar to Base N encoding, but the algorithm is quite different. It is being described on the RFC 4648. I have implemented that algorithm but any alphabet and any base encoding on the Caffeine Project — you can use base 128 if you want — and the difference with other implementations is the fact that it can handle streaming data, so you can create base encoded streams, and do not requires fixed size buffers. The standard functions can encode fixed size buffers, and encode_stream and decode_stream can encode and decode streaming buffers. You can see the source code here.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | One comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/base-conversion-tricks/feed/ 1
type safety is not security http://coder.cl/2012/10/type-safety-is-not-security/ http://coder.cl/2012/10/type-safety-is-not-security/#comments Tue, 02 Oct 2012 11:58:17 +0000 Daniel Molina Wegener http://coder.cl/?p=2840 Standar ML is defined as safe using the following definition «ML is safe, in that a program that passes the type-checker cannot dump core, access private fields of abstract data types, mistake integers for pointers, or otherwise “go wrong.”». A type-checker verifies that each term used in the programming language should have the correct type once it is used. For example if a function is defined to receive an integer type, once it is called, an integer term should be used, otherwise the compiler may throw an error and the execution “goes wrong”. If the type-checking algorithm accepts the program, then it is well-typed. When a programming language has a type-checking algorithm on its compiler, we call it statically-typed. Dynamic typing does not have a type checker on its compiler, you can write the same function, it will not have any sentence defining an input type, and it will be able to receive a string when an integer is required.

Static typing have its basis on the “Semantic Soundness Theorem”. This theorem states that an environment p is on the domain of the type environment Γ, where each variable x in p respects the environment Γ. Then, if an expression e has the type τ in the environment Γ and the environment p respects Γ, the expression e in p has the type τ. In other words — if you have experience with Haskell or Standard ML — once you create a function of type τ, the function as expression should have the type τ. Seen from another perspective, if you define a function prototype in C as double f (double x), the type-checker will not allow another type than double.

There are two types of soundness, where we have weak and strong soundness. On weak soundness we can do some tasks like type casts, with strong soundness we cannot. On Java we can type cast returning values to another type, and the compiler will allow that. On other languages, like Haskell, type casting is implemented using its type system, but we cannot type cast variables using expression built in the compiler, because the type system uses strong soundness and does not have type casting operators, and each compile time error has a type, on Java each non related type — which is being type casted — does not have its own type. On strong soundness each variable and expression is strictly bound to a type within an error with the wrong type.

Java is not type-safe because it allows a very powerful way of organizing the type-space at run-time (through user-extensible class loaders ). This power can be utilized to write a program that exposes some flawed design decisions in the Java Virtual Machine. Specifically, one can produce a class A and an associated ersatz class A’ which can “spoof” A: its name N is the same as A, but it defines members (fields and methods) arbitrarily differently from A. A “bridge ” class B can be defined which delivers to a class D (for which the name N is associated with A’) an instance of A. D can then operate on this instance as if it is an instance of A’, thus violating type-safety. [Vijay Saraswat, “Java is not type-safe”].

We can have type safety implemented on the compiler using a type checker in compile-time, like Java does. Seems that it is not entirely safe on run-time, due to the research quote above. But seems that languages like Haskell are type-safe languages in compile-time too. But can you ask yourself what is the scope of type-checkers and its type-safety?. For me type-safety aims to be the correctness prover for each program. Like Agda and Haskell does, “a proof is a program; the formula it proves is a type for the program”. So, safety is not strictly bound to security, and it just defines the correctness of the program, not its environment.

I wanted to see how great Haskell’s static typing is, so I ran darcs under an LD_PRELOAD library that had a hacked open() call. [Zed Shaw, Twitter Quote].

Type safety just brings correctness, not security. Correctness provides security — in example a string cannot be used as integer — but not provides a full security layer, and we can define that type safety brings security in terms of correctness, and not its environment. Once a program is compiled, we cannot control its environment. With some very reduced set of examples, like Plesk. For example on not so early stage as web developer, I had a problem with Apache in the compiled version inside Plesk, giving me a core dump due to some Unicode characters on a configuration file, so I have tried to use the well known Linux strace(1), I have noticed that Plesk binaries were not allowed to run with the processor debug flags enabled. That is a way to control the environment, but I certainly cannot imagine a run-time enabled type-checker. What should be verified? Each variable?, Each function parameter?.

Although verification of type safety is not mandatory to run managed code, type safety plays a crucial role in assembly isolation and security enforcement. When code is type safe, the common language runtime can completely isolate assemblies from each other. This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability. [Microsoft .NET Framework 4.5, “Type Safety and Security”].

I cannot expect that type-safety will bring me security. It only brings correctness in some manner, and the provided security only defined in terms of program correctness, rather than environmental. That is the common approach and I agree with it, we cannot expect that each program in our operating system keeps checking its environment and searching for flaws, that is a little bit weird and paranoid.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | One comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/10/type-safety-is-not-security/feed/ 1
CSDS is comming… http://coder.cl/2012/09/csds-is-comming/ http://coder.cl/2012/09/csds-is-comming/#comments Wed, 26 Sep 2012 18:14:26 +0000 Daniel Molina Wegener http://coder.cl/?p=2810 I have started a new project on Haskell. It is called CSDS, or Core Stateful Data Structures. It will hold common functional data structures, mostly based on the implementation described on the book “Purely Functional Data Structures”, but on Haskell I am using type classes and implementing some common interfaces for that kind of data structures. Is very nice to work on project like this, I think that I will use this kind of project on integrations with projects like Cloud Haskell, for distributed processing. For example some of them like the StackLT and QueueLT are providing a class interface to work with the Foldable and Monoid type classes.

Is interesting to see how some interfaces cannot be dually implemented, like PrioQueueLT cannot implement the Foldable type class. I will think a little bit more on those data structures, and still they are not fully stateful, despite they are using single-write and single-read approach. The StackLTClass type class have enough method to allow you some flexible implementations, mainly using StackLT.


class StackLClass t where
    type SLT t
    emptyS :: t
    isEmptyS :: t -> Bool
    pushS :: SLT t -> t -> t
    popS :: t -> (SLT t, t)
    lengthS :: t -> Int
    reverseS :: t -> t
    fromListS :: [SLT t] -> t
    toListS :: t -> [SLT t]
    stackLTSize :: t -> Int
    stackLTList :: t -> [SLT t]
    sortS :: (Ord (SLT t)) => t -> t
    foldlS :: (t -> SLT t -> t) -> t -> t
    mapConcatS :: (SLT t -> SLT t) -> [t] -> t
    singletonS :: SLT t -> t

If you can see the type class structure, it have some method that should allow you to work with distributed and parallel processing using Cloud Haskell and the Par Monad. I think that you will be able to work on several problems with this library. As usual I am using static checkers among other tools to ensure the quality of the code and I am coding constructs that are almost entirely compatible with Agda, so this library will be come a formally verified library of stateful data structures.

Also I will implement Typeable type class on almost all structures, this will allow you to identify network streams of data with serialized Haskell constructs, mainly where the type is not clearly defined and the processing functions or type classes are using type variables. The main goal is to use a very flexible approach, but as much strict that Haskell and Agda can handle. You are invited to participate on the development of this project at github.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/csds-is-comming/feed/ 0
choose C or C++ http://coder.cl/2012/09/choose-c-or-c/ http://coder.cl/2012/09/choose-c-or-c/#comments Tue, 18 Sep 2012 14:07:25 +0000 Daniel Molina Wegener http://coder.cl/?p=2793 How to choose between C and C++?. The answer is pretty clear. C allows powerful data type abstractions using three star and two star pointers, C++ only allows one star pointers. Also void pointers on C are more powerful once you try to pass abstract parameters to functions and procedures. The abstractions on C++ are built on top of virtual classes and templates, not its data types as C does. So, if you need to create complex data types, for example to handle hardware buffers, you should use C rather than C++, but if you want to create abstractions to manage real life objects, an object oriented interface like C++ does have is pretty good, enough to support almost any object oriented abstraction that you want to implement.

Another interesting fact is how you can integrate both C and C++ libraries and programs without too much effort. For example for the lower level of abstractions in our ProView systems, we are using C interfaces to reach the hardware layer, but that layer has an abstraction layer that allow us to see each device as a C++ class, so we can get device status, device errors, device data among other interesting operations as one single object instance, rather than using device descriptors or data structure pointers. So, we can operate each device instance, even if that device is a composite device that drives multiple sub-devices, as one single object instance with its own data and methods. That makes our life much easier than handling devices as data structures and plain C routines.

For example we have named a composite device PCU or Pump Control Unit, which consist on a pump control, an actuator control, a valve control and two manometers. It is very nice to see that PCU as one device, using plain methods over the PCU rather than using multiple plain C calls over their C data structures and pointers using each sub-device to control the unit. Even if they are using different protocols, we can operate each device transparently, thanks to every abstraction layer that we have placed on the system.

Choosing between C and C++ is not a religious choice. Mainly because I am a language agnostic programmer, and I work with limited set of programming languages where I can find better programmers, like C, C++, Python, Haskell and Lisp. Also I can choose Haskell if I want, because it supports low level function calling thanks to the Foreign Function Interface, where I can create low level interfaces for hardware devices and operate them in higher level using Haskell. For your surprise, I can create complex control algorithms in Haskell, migrate those algorithms to Agda, and create the proper proofs on those controlling algorithms. The result is a formally verified control algorithm. I can do the same with Coq and Haskell program extraction. A simple example for FFI code, is the GeoIP library interface that I have made on my ApacheLogRev project, and you can see the source code here.

So, is much better to be a language agnostic programmer than be linked to programming languages as religions…


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/choose-c-or-c/feed/ 0
monoids in haskell http://coder.cl/2012/09/monoids-in-haskell/ http://coder.cl/2012/09/monoids-in-haskell/#comments Thu, 06 Sep 2012 09:52:41 +0000 Daniel Molina Wegener http://coder.cl/?p=2730 A Monoid is a well known abstraction where you have an operation or function, a neutral element and a set that can be operated with that operation or function. Given that description, on Haskell you have an already defined Monoid class which is implemented on common types like Strings. The main monoidal String operation is the concatenation, using the (++) operation, so can have a clear example of the given description in the code that follows.


module Main (main) where

import Data.Monoid

main :: IO ()
main = let n = "x" `mappend` "y" `mappend` "z"
       in putStrLn n

The code above will produce the output xyz, because the default monidal form of the String is defined as \langle String, [], (++) \rangle, which has its formal definition as Monoid as \langle \cdot, \varepsilon, A \rangle, where \cdot is the operation — using (++) for the default string Monoid — \varepsilon is the neutral element — using [] or “” for the default string Monoid — and A is the set to operate — using the String type as set.

With this string description, we can clearly define, for example, a audio streaming IO Monad that appends stream buffers using a monoidal form. The default Monoid class definition in Haskell defines three main monoidal operations called mempty, mappend and mconcat, using a single class variable or type binding as set and allowing a non strict monoidal implementation of the class, but clear enough to be used without too much documentation, due to its natural description.


class Monoid a where
    mempty :: a
    mappend :: a -> a -> a
    mconcat :: [a] -> a

Where mempty is the neutral element, mappend is the applied operation between two members of the set — in this case a class variable — and mconcat which applies mappend on the given subset of a class variable list using the mappend definition acting as folding function. On a previous post, we have defined the Monoid class on Python, and due to its dynamic type system, that class seems to be untyped, and due to the strong-static type system in Haskell each Monoid class should be defined with a type binding. On the “re: monoids in python” post, we have seen a challenge, as follows.

  1. Using only listm, how would you concatenate a list of lists. That is, how would you transform [[a, b, c], [d, e], [f], []] into [a, b, c, d, e, f]?
  2. The reverse of a monoid is a monoid where the operator take its arguments in reverse order. Create a method, reverse, that creates a reverse monoid. What is listm.reverse()?
  3. Are there monoids that are fixed-points of the star method? That is, is there a monoid m such that m and m.star() are indistinguishable? (Side challenge: formalize the notion of “indistinguishable”.)
  4. Do monoids have a dual concept? Monoids, as defined here, are roughly an embodiment of “map/reduce”, which is used to process and analyze data, potentially taking a large body of data and reducing it. Is there a similar concept, a “comonoid”, that generates data, instead of reducing it?
  5. Let lift = int, and let op return an int. Can we enumerate all possible monoids? If not, what can we enumerate?

For the first challenge (No. 1), the listm Monoid is the list monoid. As Haskell does have a previously defined listm with the the proper Monoid class instance, beating this challenge in Haskell is almost clear, without using too much code.


module Main (main) where

import Data.Monoid

main :: IO ()
main = let n = mconcat [['a', 'b', 'c'], ['d', 'e'], ['f'], []]
       in putStrLn $ show n

The second challenge is easy to solve too. At least for listm, you can use the reverse function to revert the evaluation order of list arguments.


module Main (main) where

import Data.Monoid

main :: IO ()
main = let n = (reverse [1, 2, 3]) `mappend` (reverse [4, 5, 6])
       in putStrLn $ show n

As Python does, the \langle str, str(), + \rangle Monoid is a fixed-point Monoid and Haskell has the same fixed-point Monoid as it was described as \langle String, [], (++) \rangle, and you can appreciate the results as follows.


module Main (main) where

import Data.Foldable
import Data.Monoid

main :: IO ()
main = let n = ['a', 'b', 'c'] `mappend` "123"
           m = "abc" `mappend` ['1', '2', '3']
       in (putStrLn $ show n)
          >> (putStrLn $ show m)

If you implement a streaming IO Monad that appends stream buffers using a Monoid instance, you will have a Co-Monoid generating data, mainly if it has a separate audio and video processing, so you will have a separate channels for both streams with different data types, using one input stream. For example if you have a transmission from a radio station, where you have streaming audio for the radio signal and live show from Internet, so you can process both streams from one single stream which is being processed using the mappend over retrieved buffers.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/09/monoids-in-haskell/feed/ 0
implementing DSLs in haskell http://coder.cl/2012/08/implementing-dsls-in-haskell/ http://coder.cl/2012/08/implementing-dsls-in-haskell/#comments Tue, 28 Aug 2012 12:01:03 +0000 Daniel Molina Wegener http://coder.cl/?p=2694 Haskell is a purely functional language with a strong-static typing system. That does not means that you cannot build a compiler using Haskell, and you have a wide variety of compiler constructions libraries and tools. The one that I use in many cases is Parsec. Parsec is a monadic combinator based parser generator that can be modified in runtime, and you do not compile its specification, because it is written directly in Haskell using its set of combinators, providing a very dynamic behavior and allowing a wide variety of possible implementations. Recently on the blog www.programando.org, was launched a challenge to construct a DSL parser for L-System specifications.

The specification is not so hard to handle from the Parsec perspective. If you want a faster parsing, you can use Attoparsec instead of Parsec, and if you want compiled parser from BNF like specifications, you must use another parser generator like Happy. An example of the DSL language is as follows:


lar 20
ang 60
axi A
A:A+ZF++ZF-FA--FAFA-ZF+
Z:-FA+ZFZF++ZF+FA--FA-A
iter 2

If you observe the code, it is just a line oriented DSL, each line contains one instructions, and the “\n” and “\r” characters are instruction delimiters. There is only one variable specifier, that keeps organizing the L-System sequences, allowing the number of iterations to be specified with the iter instruction. So, the basic parser looks as follows — with the evident problem of having a strict evaluation order, but meets the requirement.



data LSysCompSet = LSysCompSet {
  lLar           :: LSLarArg
  , lAng         :: LSAngArg
  , lAxi         :: LSAxiArg
  , lSeqI        :: [LSLSysComp]
  , lIter        :: Integer
  } deriving (Eq, Show)


parLSysCompSet :: Parser LSysCompSet
parLSysCompSet = do
  _ <- parEol
  l <- parLsLar
  a <- parLsAng
  x <- parLsAxi
  s <- many parLSysComp
  r <- parLsIterComp
  _ <- parEol
  return LSysCompSet {
    lLar = l
    , lAng = a
    , lAxi = x
    , lSeqI = s
    , lIter = r
  }


So, the DSL specification is compiled into the LSysCompSet data type, holding the full instructions set of the DSL. In other cases, like processing DSLs, you can perfectly compile the instruction set to calling functions, and even to bytecode for any kind of machine. So, Haskell parser generators are really cool, just imagine the number of options that can have a combinator based parser generator. If you see the code the instructions placed on Haskell code are pretty clear, without offuscated loops and iterations made on top of BNF parser generators. You can find the full parser generator example on for the L-System drawing tool on github here.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/08/implementing-dsls-in-haskell/feed/ 0
programming and learning curves http://coder.cl/2012/08/programming-and-learning-curves/ http://coder.cl/2012/08/programming-and-learning-curves/#comments Thu, 09 Aug 2012 13:29:54 +0000 Daniel Molina Wegener http://coder.cl/?p=2668 If you have pretty clear programming concepts, learning new programming languages is not so hard as it seems. But those concepts are hard to understand. I will use my most recent learnt programming language, where probably you already know about what is it. Haskell is a programming language fulfilled with concepts, mostly based on mathematical abstractions inherited from Lambda Calculus, Combinatory Logic and Category Theory, among other topics that are covering its well known constructs, like Monads — which is inherited from Category Theory. You can understand how to work with Monads, like the IO Monad, StateMonad, and similar ones, but you need to understand the Monad basis from the perspective of the Category Theory to build your own Monads as abstractions. I am pretty sure that you can find theoretical basis on most programming abstractions, once you understand those theoretical basis, you are able to build well structured abstractions by yourself. Even if your knowledge on each topic is not so deep an abstraction variant, you can understand those concepts behind each construct and implement not so formal variants of each abstraction.

I will use the classic discussion about the Monadic perspective of jQuery. Along Monad implementations, you have a natural transformation from a type B to a composite type A B, to build chained or sequenced computations with identity. But the sequence or computation chain type is preserved along the process, as it is required from its formal definition. On jQuery you lost that composite type, falling in different composite types along the computation chain.


$('#select-node-id').
    find('element').
    each(function (idx, elm) {
        $(elm).attr('id', 'seq' + idx);
    }).
    addClass('list-nodes').
    find('element:first').
    addClass('first');

If you have a look on the code snippet above, you have a computation chain, where the composite type can vary between Node String, NodeList String and DOMString String. In other words those types are three different composite types A B, A C and A D. The type sequence can be enumerated as follows.

  1. Node DOMString
  2. NodeList DOMString
  3. NodeList DOMString
  4. Node DOMString
  5. NodeList DOMString
  6. Node DOMString
  7. Node DOMString
  8. Node DOMString

If the chain or sequence is loosing its type, which its identity should be bound to that type, jQuery is not a Monad. Please have a look on the Document Object Model (DOM) class diagram bellow. So, each type on the sequence have an unbound type, and the last selected node in the sequence have a different type, where the last Monad have a different composite type from the original requested composite type. This breaks the identity Monadic law, as does every change on the composite type along the sequence.

Document Object Model Class Diagram

Document Object Model Class Diagram

A Haskellish solution is to create a second composite type as follows.


data NodeSelector = NodeSelector DOMString deriving (Eq, Show)


data NodeUntyped = Node NodeSelector
                   | NodeList NodeSelector
                   | DOMString NodeSelector
                   deriving (Eq, Show)


newtype NodesM n = NodesM n { toNode :: n }


instance Monad NodesM where
  return = NodesM
  f >>= g = g $ toNode f

Where each operation — to make it Monadic — should be implemented over NodesM NodeUntyped, without variants on the bound type as meeting the identity and transformation Monadic laws. This will preserve the required set of Categories that meets the original model. If you do not have a clear concepts about a language, you cannot understand the language itself.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/08/programming-and-learning-curves/feed/ 0
flow control data types http://coder.cl/2012/07/flow-control-data-types/ http://coder.cl/2012/07/flow-control-data-types/#comments Wed, 04 Jul 2012 16:31:57 +0000 Daniel Molina Wegener http://coder.cl/?p=2571 Static typing and dynamic typing usually are offering null references as solution for the not an object problem. With strong-static typing systems, there are not null references, because there is nothing that can be treated as wild-card type, as Object() in Java and void * in C and C++ — everything have a type. So, there are some flow control structures allowing the programmer to handle the not an object problem using composite data types. Classical examples are the Maybe Monad and the Either Monad in Haskell. Both of them, allow you to control the behaviour of the program using a composite type to bind null reference requirements.


-- | The type of strict optional values.
data Maybe a = Nothing | Just !a deriving (Eq, Ord, Show, Read)

Maybe is a composite data type with algebraic form which encapsulates a type instance or an empty instance called Nothing. It meets the Monad requirements since it has the curried form * → * and allows you to hide the real instance inside all Monadic operations of the encapsulated instance. How it is being used? Please review the following example.


module Main (main) where

import Data.Maybe

sum2 :: Maybe Int -> Maybe Int -> Maybe Int
sum2 Nothing Nothing = Nothing
sum2 Nothing n = Nothing
sum2 n Nothing = Nothing
sum2 (Just n) (Just m) = Just $ n + m

main :: IO ()
main = let a = sum2 (Just 10) Nothing
           in print $ fromJust a

The example above receives a two composite Maybe Int variables and returns a Maybe Int instance. We can tell that the function above is safe, because it handles null references properly. Only with Just !a input variables it is executing the sum2 operation, in other case, it preserves the Nothing instance. To make it safe, we can ask if the resulting output is really a valid variable that can be handled by fromJust function.


main :: IO ()
main = let a = sum2 (Just 10) Nothing
           in if isNothing a
                 then print "Nothing"
                 else print $ fromJust a

But there is no not an object reference “until it is declared”. So, this is a composite type of kind Algebraic Data Type due to its curried form. But there is another powerful composite type that allows you to encapsulate dual results, not as it is being made with the Maybe Monad, but with two type variables allowing the composition between two optional types, which is called Either Monad.


-- | The strict choice type.
data Either a b = Left !a | Right !b deriving (Eq, Ord, Read, Show)

Either encapsulates the type variables a and b. For example, due to its strong-static typing nature, Haskell does not allow to operate between floating point numbers and integer numbers, so we need explicit transformation functions to operate on them. So, the following example sum3 works with this approach and a type * → * → *.


module Main (main) where

import Data.Either

sum3 :: Either Int Float
        -> Either Int Float
        -> Either Int Float
sum3 (Right a) (Left b) = Right $ a + fromIntegral b
sum3 (Left a) (Right b) = Right $ fromIntegral a + b
sum3 (Right a) (Right b) = Right $ a + b
sum3 (Left a) (Left b) = Left $ a + b

main :: IO ()
main = let a = sum3 (Right 0.1) (Right 0.2)
           in case a of
                   Left  n -> print $ "Left:  " ++ show n
                   Right n -> print $ "Right: " ++ show n

So, the Either data type on the example above is encapsulating the Int and Float types. And you can combine many composite types as you need, for example we can do another version handling Either (Maybe Int) Float and still it will be valid, allowing null references for the integer part of the composite type. So, the limit on null references is embedded in the language, and usage of null references or not an object instances depends exclusively on you. Just imagine the amount of errors that can be reduced with strong-static typing.


© Daniel Molina Wegener for coder . cl, 2012. | Permalink | No comment | Add to del.icio.us
Post tags:

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

]]>
http://coder.cl/2012/07/flow-control-data-types/feed/ 0