Jump to content

  • Log In with Google      Sign In   
  • Create Account


Daerax

Member Since 01 Aug 2002
Offline Last Active Feb 02 2012 11:35 AM
-----

Topics I've Started

Children of Tomorrow - How far

13 February 2009 - 01:40 PM

would you go?. If I knew I could reduce my child's chance of getting certain diseases and disabilities I would certainly not hesitate to shell out the money. If I could increase their potential intelligence and athletic ability I would only hesitate 5 seconds (prisoners dilemma applies here with other families, you see). Will this only serve to further polarize the world and increase the poverty gap? Is that ethical? What would you do? How would this be legislated? Should genetic engineering be banned or heavily controlled? Do you think we might start seeing tiger people?

A question on Syntax

02 September 2008 - 03:03 AM

Do you prefer a terse syntax or a more verbose one? Or something more in between? Is it possible for a language to be too terse? Where the term write only language becomes true (see APL or K. code:
(!R)@&{&/x!/:2_!x}'!R
taken from wiki). Is there added expressiveness and power in terseness? The key answer of this survey I am seeking is where do you think the balance is struck and if you swing closer to verbose (C++, Java,VB etc) what is gained by the added loquaciousness?

Monads on .NET

03 August 2008 - 11:26 AM

WARNING: This is a long post. If you are not interested in Programming language theory then this will likely bore you.
----

So Monads are a big topic. Cause the word is fairly fancy. They were discovered within the tomes of Abstract Algebra by mages from the Haskell Tower hundreds of years ago in the early 80's. Since then haskell mages have written thousands of treatises on their use.

Recently with the sudden popularity of functional programming the common Sorcerer has found the use of monads. So there is suddenly a resurgence of interest in monads.

Monads are basically a higher level of design pattern. The encompass many things including - error handling, containers, Rules System ala prolog, probabilities, quantum mechanics, groups, continuations, parsers, AI etc...

Monad combinators allow a powerful composition type methodology, myself I noticed they might be useful for expressing AI and lots o game play type code. Basically the idea is you create a basic building block of components or behaviours and then combine them by interpreting them in a sub language that almost falls out for free. I am using them to make a powerful magic system where users can create spells.

For those of you on .NET if you use linq then you have used a monad before.

Specific Monads can be implemented in any language with generics. Ability to abstract over monads requires either having a stronger type system or a weaker e.g. dynamic/freely typed system. The use of monads is their ability to capture abstraction and turn them into pure power.

Traditional Maybe Monad Using Nemerle
variant Maybev[a]  :  Maybe[a]{ 
  | Nothing
  | Just { jst : a} 
}
class Maybe [a] :  MyMonad[a] {
    public bind[b] (m : Maybev[a] ,  mb : a -> Maybev[b]) : Maybev[b]    {
     match(m){
      | Nothing => Maybev.Nothing();
      | Just(x) => mb(x)
      }}
    public static @>>>= [b](m : Maybev[a] ,  mb : a -> Maybev[b]) : Maybev[b]{
       m.bind(m,mb);
    }
    public  mreturn (x : a) : Maybev[a]{
      Maybev.Just(x);
    }}
type Just[a] = Maybev[a].Just;
type Nothing[a] = Maybev[a].Nothing;



To use:
def o = Maybev.Just(3) >>>= fun(x1){ 
                                
                                    Maybev.Just(2) >>>= fun(x2){
                                                         Maybe().mreturn(x1 + x2)
                                                 }                                  
                                                               } 
                                    


o is Just(5). But that is nothing special.

F# has these things called Workflows and computation expressions. It lets you build and comprehend monads. It is the first language on .NET to have sugared support for monads. Using Nemerle's metaprogramming feature I was able to get similar to that.

In F# you can write:
attempt { 
let! n1 = failIfBig inp1
let! n2 = failIfBig inp2
let sum = n1 + n2
return sum };;
In Nemerle with My monad dsl:
def opr = monadq(Maybe)[ 
                   p44 <== Just(3),
                   q44 <== Nothing(),  //<--The computation will bail out here and return Nothing.                    
                   returns (p44 + q44)] //<== only gets here if  ;
It is a macro which converts to the more verbose syntax. It works on any Monad. As well I am writing standard monad operations like map and fold etc as macros since the .NET type system is not flexible enough to allow that.

OUTPUT:
KKK
KKP
Car v bike
bike v Car
c v b
13
13 1
ConsoleApplication11del.Maybev`1+Nothing[System.Int32] No good Got 5 Got 5
vh?
Hi! 11 4 11 [2, 4, 6] [7, 10] (7, 10) 6 29 29 4
I was testing other things like currying, extensible matching, function operators and Existential types there.

Metaprogramming and Number Paramerterized Types

09 July 2008 - 04:29 AM

So this is just me wanting to talk about my experiences relating to the thread title. Feel free to share yours. In my opinion one of the reasons C++ still exists is because it has been extended using templates to useful directions beyond what the authors could ever have hoped.



Quite nice behaviour I did not intend was one can add 2 vectors of type Vec(n, double) and Vec(n, int) but cannot take their dot product. Notice one knows before compiling that a vector was indexed out of bounds. This is thanks to the russian group who have done a visual studio integration that does some really nice intellisense.

I recently stumbled upon the paper on Number Parameterized Types for Haskell. In there different methods are talked about which let one emulate some of the attributes of dependent types - where some invariants can be checked statically at compile time to eliminate a certain classes of errors. Looking at it, I decided such a thing would be quite useful to me so I decided to implement it on the .NET framework. Which is currently where I live thanks to all the tools and libraries.

Luckily as well, my language of choice on there is Nemerle so I was able to implement it more cleanly and flexibly than found in the paper. The whole method involves encoding the required numbers into type constructors. The core of the code is in creating a bunch of empty union types. Specifying an interface and then implementing each digit as structs matching the interface which can then be used to instantiate arbitrary classes.
    public variant D7
        | D7    
    public variant D8    
        | D8    
    public variant D9 
        | D9
   ...    
/***************************************************************************/   
    public interface Digit['a]
        ToNumber() : int

    public struct d0 : Digit[D0]
        public ToNumber() : int
            0
    public struct d1 : Digit[D1]
        public ToNumber() : int
            1
  ....



Defining a vector class: Vector ['a, 'b, 'vtype] constructor( args : Digit['a] * Digit['b], init: vtype) ....
Then one can go: def (v, v2) = (Vector(d0(), d2(), 0), Vector(d0(), d3(), 0) ; And get a compile time error when you try to add both of them. I then decided to clean it up and make it more general. Note that to allow arbitrary precision simply allow the digit union or variant types to take a data constructor.

I do not know if this is how hardcore schemers and lispers view the world but I originally intended to write a seperate set of macros and then write a library using them but then realized that the macros and the library belonged in the same package, it did not make sense separating them and only making the library visible. What I realized I was doing was language oriented programming.

For example on .NET I cannot create a polymorphic type which also contained mathematical operators since there is no Number Interface (why there is no Add(a ,b) I am unsure). To get around this I decided to create the operators as macros, since the types of the vectors will be fixed and known within the body of the functions where the usage occurs. Nemerle allows one to do metaprogramming in the same language and uses quasiquotations of nemerle code to deconstruct and construct syntax trees so one need not write obtuse code messing with the syntax tree.

Thus for example I could write:
macro @<.>(a, b) { acquire type of a and b. Use simple 9 line helper function to convert to integer. 

Compare sizes. If mismatch throw compile error. 
Else Quote: 
         <[
            def size = $vector1.Size.Upperbound;
            def arr1 = $vector1.getArrayRep();
            def arr2 = $vector2.getArrayRep();
            def zero = arr1[0] - arr1[0];
            def dotp = $[arr1[i] * arr2[i] | i in $[0 .. size-1]].FoldLeft(zero, (i,j)=> i + j);]>
. The computation is staged and only those values which are not known at compile time are deferred. To cut a long story short I wrote a bunch of macros with little effort that made using number paramertized types as part of the language simple. Then wrote a natural number package (you can add and multiply the numbers and know results before runtime) using them. Which were then used for the vectors. Vectors dimensions can only be constructed using a natural number. Although one can say def v = vec 5 this is just shorthand for def v = Vector(0, Naturals(d0(d5()))). Code of which is :
 def p = Helper.IntToTypeCons(sz);
            <[Vector(0, Naturals($p)) ]>;}
.

Anyways being able to drop down and write plugins to the compiler to make it more suit your needs when the language or framework is not expressive enough to tackle your domain is nice I feel. The only downside is being careful not to introduce too many new keywords and weird syntaxes. Although to the end user the macros not extended with new syntax are in fact indistinguishable from normal functions.

[.net] IamANumber

03 July 2008 - 02:04 AM

In Haskell you can constrain the types that a polymorphic function can take. For example limiting a type to anything that derives from the number type class: ZipListsAndSum :: (Num a) => [a] -> [a] -> a. I was looking and it seems there is no INumeric type (hehe) interface that guarantees that a type will implement certain numeric operations. Of the interfaces that would be appropriate the number types on .Net only implement IComparable and IEquatable, which do not cover all the operations I would expect from a number type. Any tips to overcome this?

PARTNERS