Enum methods

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Enum methods

Vag Vagoff
Hi!

What about extending the language to allow adding methods to enums?

interface IToString { function toString() : String; }
enum AB implements IToString {
     A( a : Int );
     B( b : String, c : Float );
     public function toString() : String {
         return switch( this ) {
             case A(a): "A(" + a.toString(); + ")";
             case B(b,c): "B(" + b + c.toString() + ")";
     }
}
class Test {
     static public function f( a : IToString ) {
         trace(a.toString());
     }
     static public function main() {
         f(A(10));
     }
}

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

clemos
Hi

You can have the same functionnality with "using" I think:

class ABTools {
  public static function toString( ab : AB ){
     return switch( ab ) {
           case A(a): "A(" + a.toString(); + ")";
           case B(b,c): "B(" + b + c.toString() + ")";
     }
  }
}

And then:
using ABTools;
class Test {
   static public function f( a : AB ) {
       trace(a.toString());
   }
   static public function main() {
       f(A(10));
   }
}

Cheers,
Clément

On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:

> Hi!
>
> What about extending the language to allow adding methods to enums?
>
> interface IToString { function toString() : String; }
> enum AB implements IToString {
>    A( a : Int );
>    B( b : String, c : Float );
>    public function toString() : String {
>        return switch( this ) {
>            case A(a): "A(" + a.toString(); + ")";
>            case B(b,c): "B(" + b + c.toString() + ")";
>    }
> }
> class Test {
>    static public function f( a : IToString ) {
>        trace(a.toString());
>    }
>    static public function main() {
>        f(A(10));
>    }
> }
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Vag Vagoff
On 13.12.2010 13:40, clemos wrote:
> You can have the same functionnality with "using" I think:

No, it's a pity. Extension methods do not implement interfaces.
So I can not do with them static public function f( a : IToString ) ...

By the way, why not allow to do "using" on library side? It will be much more convenient.

     //library:
     class IntEx { ... }
     public using IntEx;

Vag.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

John A. De Goes
In reply to this post by clemos

Nope. Extension methods do not implement interfaces, which means it's not possible to unify enums with other classes.

As a result, numerous code must be special cased. For example, in Stax there is no "Monad" interface because some of the monads (like Option) are enums which cannot implement an interface.

Regards,

John A. De Goes
Twitter: @jdegoes
LinkedIn: http://linkedin.com/in/jdegoes

On Dec 13, 2010, at 4:40 AM, clemos wrote:

> Hi
>
> You can have the same functionnality with "using" I think:
>
> class ABTools {
>  public static function toString( ab : AB ){
>     return switch( ab ) {
>           case A(a): "A(" + a.toString(); + ")";
>           case B(b,c): "B(" + b + c.toString() + ")";
>     }
>  }
> }
>
> And then:
> using ABTools;
> class Test {
>   static public function f( a : AB ) {
>       trace(a.toString());
>   }
>   static public function main() {
>       f(A(10));
>   }
> }
>
> Cheers,
> Clément
>
> On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
>> Hi!
>>
>> What about extending the language to allow adding methods to enums?
>>
>> interface IToString { function toString() : String; }
>> enum AB implements IToString {
>>    A( a : Int );
>>    B( b : String, c : Float );
>>    public function toString() : String {
>>        return switch( this ) {
>>            case A(a): "A(" + a.toString(); + ")";
>>            case B(b,c): "B(" + b + c.toString() + ")";
>>    }
>> }
>> class Test {
>>    static public function f( a : IToString ) {
>>        trace(a.toString());
>>    }
>>    static public function main() {
>>        f(A(10));
>>    }
>> }
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Nicolas Cannasse
In reply to this post by Vag Vagoff
Le 13/12/2010 12:27, Vag Vagoff a écrit :
> Hi!
>
> What about extending the language to allow adding methods to enums?

Enums might have different implementations depending on the platform.
They might even not be actual objects. I'm not in favor of blurring the
borders between pure data (enums) and OO.

Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Heinz Hölzer-2
So what do you think about my feature request some weeks ago:

http://haxe.1354130.n2.nabble.com/Feature-Request-Auto-Using-for-classes-enums-and-interfaces-very-useful-for-extern-classes-tc5694956.html#a5705274

from my point of view it would give you the best of both worlds.

Am 13.12.2010 14:32, schrieb Nicolas Cannasse:

> Le 13/12/2010 12:27, Vag Vagoff a écrit :
>> Hi!
>>
>> What about extending the language to allow adding methods to enums?
>
> Enums might have different implementations depending on the platform.
> They might even not be actual objects. I'm not in favor of blurring
> the borders between pure data (enums) and OO.
>
> Nicolas
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Juraj Kirchheim
In reply to this post by Vag Vagoff
On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
> Hi!
>
> What about extending the language to allow adding methods to enums?

As with many other problems, simple composition solves this:

class ABObject {
   public var data(default, null):AB;
   public function toString() : String {
       return switch( data ) {
           case A(a): "A(" + a.toString(); + ")";
           case B(b,c): "B(" + b + c.toString() + ")";
   }
}

Enums are not OO, as Nicolas put it.
If OO is what you want, define an interface and transform every
constructor into an implementing class and refactor switches made on
the enum into the interface.

Example:

    enum Color {
        grey( v : Int );
        rgb( r : Int, g : Int, b : Int );
    }
    class Colors {
        static function toInt( c : Color ) : Int {
            return switch( c ) {
                case grey(v): 0x010101 * v;
                case rgb(r,g,b): (r << 16) | (g << 8) | b;
            }
        }
    }

Is transformed into

   interface Color {
      function toInt():Int;
   }
   class Grey implements Color {
     //implementation
   }
   class RGB implements Color {
     //implementation
   }

**That** is OO. Because data and logic are encapsulated into distinct,
decantralized objects, while for enums data is defined in a central
manner and logic can be completely decentralized, which is a different
paradigm.

I see how your proposition provides a certain kind of comfort, but it
blurs the border between two orthogonal features and two very opposed
approaches. It affects clarity and strictness, which I think are two
core philosophies of haXe.

greetz
back2dos

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Nicolas Cannasse
In reply to this post by Heinz Hölzer-2
Le 13/12/2010 14:44, Heinz Hölzer a écrit :
> So what do you think about my feature request some weeks ago:
>
> http://haxe.1354130.n2.nabble.com/Feature-Request-Auto-Using-for-classes-enums-and-interfaces-very-useful-for-extern-classes-tc5694956.html#a5705274
>
>
> from my point of view it would give you the best of both worlds.

There are actually a lot of pending ideas both on the list and in my
mind concerning the ability to do such contextual "magic" that would
smooth object extension usability or allow some globals
functions/variables to be accessible.

I'm just not sure yet which one is better and more suitable for haXe.
Anyway thank you for your proposal ;)

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

John A. De Goes
In reply to this post by Juraj Kirchheim

You're completely wrong, of course.

Every other high-level language having enums or enum-like data has a way to abstract across type hierarchies. Not so with HaXe enums.

For example, I wanted to represent List as:

enum List<T> {
  Cons(head: T, tail: List<T>);
  Nil;
}

This is the idiomatic representation with algebraic data types. Unfortunately, it's crap in HaXe because even though you can "add" methods such as size, head, tail, drop, concat, fold, map, filter, etc., you cannot unify across List and other collection types (such as Maps) which cannot be implemented using enums.

So there's no way to both (1) represent List using an enum, and (2) create a unified collection library that allows some code to be agnostic with respect to what kind of collection they are receiving.

Similarly, Stax uses Option to denote the presence/absence of a value:

enum Option<T> {
  Some(t: T);
  None;
}

Enum is in fact a monad, and it would be great if code that can work on any monad can just accept a Monad<T>, but because it's impossible to abstract over enums (enums cannot implement interfaces!), I instead just have to duplicate tons of code for every enum and accept that code must be special cased depending on the kind of monad (enum or class based).

The decision to disallow abstraction over enums results in much code duplication, and leaves enums impotent for any serious task; they are fit only for the simplest of use cases, and do not offer the power of, for example, Haskell's algebraic data types, which allow full abstraction via type classes.

Regards,

John A. De Goes
Twitter: @jdegoes 
LinkedIn: http://linkedin.com/in/jdegoes

On Dec 14, 2010, at 8:12 AM, Juraj Kirchheim wrote:

On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
Hi!

What about extending the language to allow adding methods to enums?

As with many other problems, simple composition solves this:

class ABObject {
  public var data(default, null):AB;
  public function toString() : String {
      return switch( data ) {
          case A(a): "A(" + a.toString(); + ")";
          case B(b,c): "B(" + b + c.toString() + ")";
  }
}

Enums are not OO, as Nicolas put it.
If OO is what you want, define an interface and transform every
constructor into an implementing class and refactor switches made on
the enum into the interface.

Example:

   enum Color {
       grey( v : Int );
       rgb( r : Int, g : Int, b : Int );
   }
   class Colors {
       static function toInt( c : Color ) : Int {
           return switch( c ) {
               case grey(v): 0x010101 * v;
               case rgb(r,g,b): (r << 16) | (g << 8) | b;
           }
       }
   }

Is transformed into

  interface Color {
     function toInt():Int;
  }
  class Grey implements Color {
    //implementation
  }
  class RGB implements Color {
    //implementation
  }

**That** is OO. Because data and logic are encapsulated into distinct,
decantralized objects, while for enums data is defined in a central
manner and logic can be completely decentralized, which is a different
paradigm.

I see how your proposition provides a certain kind of comfort, but it
blurs the border between two orthogonal features and two very opposed
approaches. It affects clarity and strictness, which I think are two
core philosophies of haXe.

greetz
back2dos

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Vag Vagoff
On 15.12.2010 18:49, John A. De Goes wrote:
 > For example, I wanted to represent List as:
 >
 >     enum List<T> {
 >     Cons(head: T, tail: List<T>);
 >     Nil;
 >     }
 >

Interestingly enough, how these idiomatic FP lists will be seen from OOP perspective:

class List<T> {
     public function isNil() : Bool return throw "abstract"
     public function isCons() : Bool return throw "abstract"
     public function match<R>( onCons : Cons<T> -> R, onNil : Nil<T> -> R ) : R return throw "abstract"
     public function head() : T return throw "abstract"
     public function tail() : List<T> return throw "abstract"
     public static function Cons<T>( h : T, t : List<T> ) : List<T> return new Cons(h,t)
     public static function Nil<T>() : List<T> return new Nil()
     public static function concat<T>( a : List<T>, b : List<T> ) : List<T> {
         return a.match(
             function(cons) return List.Cons(cons.head(),concat(cons.tail(),b)),
             function(nil) return b
         );
     }
}

class Cons<T> extends List<T> {
     var h : T;
     var t : List<T>;
     public function new(h_,t_) { h = h_; t = t_; }
     override function isNil() : Bool return false
     override function isCons() : Bool return true
     override function match(onCons,onNil) return onCons(this)
     override function head() : T return h
     override function tail() : List<T> return t
}

class Nil<T> extends List<T> {
     public function new() {}
     override public function isNil() : Bool return true
     override public function isCons() : Bool return false
     override function match(onCons,onNil) return onNil(this)
     override public function head() : T return null
     override public function tail() : List<T> return null
}

class Test {
     static function main() {
         var a = List.Cons(1,List.Cons(2,List.Nil()));
         var b = List.Cons(3,List.Nil());
         trace(a);
         trace(b);
         trace(a.head());
         trace(a.tail());
         var c = List.concat(a,b);
         trace(c);
     }
}

Not so bad (modulo huge syntactic clutter, of course).

Am I OOPish enough in method match()? Someone claim that OOP must completely eliminate switches, but I have here
switch-like destructor emulated on higher order functions.

Vag.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

John A. De Goes

I implemented them using OOP (see the Stax source code). However, this implementation technique lacks the ability to perform pattern matching on lists in a type-safe way.

Although pattern matching does not yet support nested constructs, as soon as it does, pattern matching on lists will enable very elegant functional solutions to many problems.

Regards,

John A. De Goes
Twitter: @jdegoes
LinkedIn: http://linkedin.com/in/jdegoes

On Dec 16, 2010, at 2:24 AM, Vag Vagoff wrote:

> On 15.12.2010 18:49, John A. De Goes wrote:
> > For example, I wanted to represent List as:
> >
> >     enum List<T> {
> >     Cons(head: T, tail: List<T>);
> >     Nil;
> >     }
> >
>
> Interestingly enough, how these idiomatic FP lists will be seen from OOP perspective:
>
> class List<T> {
>    public function isNil() : Bool return throw "abstract"
>    public function isCons() : Bool return throw "abstract"
>    public function match<R>( onCons : Cons<T> -> R, onNil : Nil<T> -> R ) : R return throw "abstract"
>    public function head() : T return throw "abstract"
>    public function tail() : List<T> return throw "abstract"
>    public static function Cons<T>( h : T, t : List<T> ) : List<T> return new Cons(h,t)
>    public static function Nil<T>() : List<T> return new Nil()
>    public static function concat<T>( a : List<T>, b : List<T> ) : List<T> {
>        return a.match(
>            function(cons) return List.Cons(cons.head(),concat(cons.tail(),b)),
>            function(nil) return b
>        );
>    }
> }
>
> class Cons<T> extends List<T> {
>    var h : T;
>    var t : List<T>;
>    public function new(h_,t_) { h = h_; t = t_; }
>    override function isNil() : Bool return false
>    override function isCons() : Bool return true
>    override function match(onCons,onNil) return onCons(this)
>    override function head() : T return h
>    override function tail() : List<T> return t
> }
>
> class Nil<T> extends List<T> {
>    public function new() {}
>    override public function isNil() : Bool return true
>    override public function isCons() : Bool return false
>    override function match(onCons,onNil) return onNil(this)
>    override public function head() : T return null
>    override public function tail() : List<T> return null
> }
>
> class Test {
>    static function main() {
>        var a = List.Cons(1,List.Cons(2,List.Nil()));
>        var b = List.Cons(3,List.Nil());
>        trace(a);
>        trace(b);
>        trace(a.head());
>        trace(a.tail());
>        var c = List.concat(a,b);
>        trace(c);
>    }
> }
>
> Not so bad (modulo huge syntactic clutter, of course).
>
> Am I OOPish enough in method match()? Someone claim that OOP must completely eliminate switches, but I have here
> switch-like destructor emulated on higher order functions.
>
> Vag.
>
> --
> haXe - an open source web programming language
> http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Juraj Kirchheim
In reply to this post by John A. De Goes
Yes, and virtually any other high level language allows abstraction
over integers.
haXe enums are primitive types. Full stop. Just because Sun thought

On Wed, Dec 15, 2010 at 5:49 PM, John A. De Goes <[hidden email]> wrote:

>
> You're completely wrong, of course.
> Every other high-level language having enums or enum-like data has a way to
> abstract across type hierarchies. Not so with HaXe enums.
> For example, I wanted to represent List as:
>
> enum List<T> {
>   Cons(head: T, tail: List<T>);
>   Nil;
> }
>
> This is the idiomatic representation with algebraic data types.
> Unfortunately, it's crap in HaXe because even though you can "add" methods
> such as size, head, tail, drop, concat, fold, map, filter, etc., you cannot
> unify across List and other collection types (such as Maps) which cannot be
> implemented using enums.
> So there's no way to both (1) represent List using an enum, and (2) create a
> unified collection library that allows some code to be agnostic with respect
> to what kind of collection they are receiving.
> Similarly, Stax uses Option to denote the presence/absence of a value:
>
> enum Option<T> {
>   Some(t: T);
>   None;
> }
>
> Enum is in fact a monad, and it would be great if code that can work on any
> monad can just accept a Monad<T>, but because it's impossible to abstract
> over enums (enums cannot implement interfaces!), I instead just have to
> duplicate tons of code for every enum and accept that code must be special
> cased depending on the kind of monad (enum or class based).
> The decision to disallow abstraction over enums results in much code
> duplication, and leaves enums impotent for any serious task; they are fit
> only for the simplest of use cases, and do not offer the power of, for
> example, Haskell's algebraic data types, which allow full abstraction via
> type classes.
> Regards,
> John A. De Goes
> Twitter: @jdegoes
> LinkedIn: http://linkedin.com/in/jdegoes
> On Dec 14, 2010, at 8:12 AM, Juraj Kirchheim wrote:
>
> On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
>
> Hi!
>
> What about extending the language to allow adding methods to enums?
>
> As with many other problems, simple composition solves this:
>
> class ABObject {
>   public var data(default, null):AB;
>   public function toString() : String {
>       return switch( data ) {
>           case A(a): "A(" + a.toString(); + ")";
>           case B(b,c): "B(" + b + c.toString() + ")";
>   }
> }
>
> Enums are not OO, as Nicolas put it.
> If OO is what you want, define an interface and transform every
> constructor into an implementing class and refactor switches made on
> the enum into the interface.
>
> Example:
>
>    enum Color {
>        grey( v : Int );
>        rgb( r : Int, g : Int, b : Int );
>    }
>    class Colors {
>        static function toInt( c : Color ) : Int {
>            return switch( c ) {
>                case grey(v): 0x010101 * v;
>                case rgb(r,g,b): (r << 16) | (g << 8) | b;
>            }
>        }
>    }
>
> Is transformed into
>
>   interface Color {
>      function toInt():Int;
>   }
>   class Grey implements Color {
>     //implementation
>   }
>   class RGB implements Color {
>     //implementation
>   }
>
> **That** is OO. Because data and logic are encapsulated into distinct,
> decantralized objects, while for enums data is defined in a central
> manner and logic can be completely decentralized, which is a different
> paradigm.
>
> I see how your proposition provides a certain kind of comfort, but it
> blurs the border between two orthogonal features and two very opposed
> approaches. It affects clarity and strictness, which I think are two
> core philosophies of haXe.
>
> greetz
> back2dos
>
> --
> haXe - an open source web programming language
> http://haxe.org
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Juraj Kirchheim
(Sorry, hit send accidentally).
Yes, and virtually any other high level language allows abstraction
over integers.
haXe enums are primitive types. Full stop. Just because Sun thought
"everything is an object" is a hip thing 15 years ago, this doesn't
mean everything has to be an object.
Everything is an object is an oversimplyfication. It is a restriction
languages as C++ and Objective-C do not have.
What you want can possibly be achieved with the suggested multitypes,
but this weird mix, as suggested, really violates OO at its core.

On Thu, Dec 16, 2010 at 7:43 PM, Juraj Kirchheim
<[hidden email]> wrote:

> Yes, and virtually any other high level language allows abstraction
> over integers.
> haXe enums are primitive types. Full stop. Just because Sun thought
>
> On Wed, Dec 15, 2010 at 5:49 PM, John A. De Goes <[hidden email]> wrote:
>>
>> You're completely wrong, of course.
>> Every other high-level language having enums or enum-like data has a way to
>> abstract across type hierarchies. Not so with HaXe enums.
>> For example, I wanted to represent List as:
>>
>> enum List<T> {
>>   Cons(head: T, tail: List<T>);
>>   Nil;
>> }
>>
>> This is the idiomatic representation with algebraic data types.
>> Unfortunately, it's crap in HaXe because even though you can "add" methods
>> such as size, head, tail, drop, concat, fold, map, filter, etc., you cannot
>> unify across List and other collection types (such as Maps) which cannot be
>> implemented using enums.
>> So there's no way to both (1) represent List using an enum, and (2) create a
>> unified collection library that allows some code to be agnostic with respect
>> to what kind of collection they are receiving.
>> Similarly, Stax uses Option to denote the presence/absence of a value:
>>
>> enum Option<T> {
>>   Some(t: T);
>>   None;
>> }
>>
>> Enum is in fact a monad, and it would be great if code that can work on any
>> monad can just accept a Monad<T>, but because it's impossible to abstract
>> over enums (enums cannot implement interfaces!), I instead just have to
>> duplicate tons of code for every enum and accept that code must be special
>> cased depending on the kind of monad (enum or class based).
>> The decision to disallow abstraction over enums results in much code
>> duplication, and leaves enums impotent for any serious task; they are fit
>> only for the simplest of use cases, and do not offer the power of, for
>> example, Haskell's algebraic data types, which allow full abstraction via
>> type classes.
>> Regards,
>> John A. De Goes
>> Twitter: @jdegoes
>> LinkedIn: http://linkedin.com/in/jdegoes
>> On Dec 14, 2010, at 8:12 AM, Juraj Kirchheim wrote:
>>
>> On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
>>
>> Hi!
>>
>> What about extending the language to allow adding methods to enums?
>>
>> As with many other problems, simple composition solves this:
>>
>> class ABObject {
>>   public var data(default, null):AB;
>>   public function toString() : String {
>>       return switch( data ) {
>>           case A(a): "A(" + a.toString(); + ")";
>>           case B(b,c): "B(" + b + c.toString() + ")";
>>   }
>> }
>>
>> Enums are not OO, as Nicolas put it.
>> If OO is what you want, define an interface and transform every
>> constructor into an implementing class and refactor switches made on
>> the enum into the interface.
>>
>> Example:
>>
>>    enum Color {
>>        grey( v : Int );
>>        rgb( r : Int, g : Int, b : Int );
>>    }
>>    class Colors {
>>        static function toInt( c : Color ) : Int {
>>            return switch( c ) {
>>                case grey(v): 0x010101 * v;
>>                case rgb(r,g,b): (r << 16) | (g << 8) | b;
>>            }
>>        }
>>    }
>>
>> Is transformed into
>>
>>   interface Color {
>>      function toInt():Int;
>>   }
>>   class Grey implements Color {
>>     //implementation
>>   }
>>   class RGB implements Color {
>>     //implementation
>>   }
>>
>> **That** is OO. Because data and logic are encapsulated into distinct,
>> decantralized objects, while for enums data is defined in a central
>> manner and logic can be completely decentralized, which is a different
>> paradigm.
>>
>> I see how your proposition provides a certain kind of comfort, but it
>> blurs the border between two orthogonal features and two very opposed
>> approaches. It affects clarity and strictness, which I think are two
>> core philosophies of haXe.
>>
>> greetz
>> back2dos
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Cauê W.
In reply to this post by Juraj Kirchheim
BTW, is there any restriction on haXe spec about nullable enums?? On C#, parameterless enums and enums that bear a @:struct annotation / that allocate less than 32 bytes (if I recall well, can be 16), are non-nullable. This means that testing against null will actually test against a parameterless enum's first case, or against an empty parameter enum (can't be generated from inside haxe code, though). Of course Null<MyEnum> will work properly

2010/12/16 Juraj Kirchheim <[hidden email]>
Yes, and virtually any other high level language allows abstraction
over integers.
haXe enums are primitive types. Full stop. Just because Sun thought

On Wed, Dec 15, 2010 at 5:49 PM, John A. De Goes <[hidden email]> wrote:
>
> You're completely wrong, of course.
> Every other high-level language having enums or enum-like data has a way to
> abstract across type hierarchies. Not so with HaXe enums.
> For example, I wanted to represent List as:
>
> enum List<T> {
>   Cons(head: T, tail: List<T>);
>   Nil;
> }
>
> This is the idiomatic representation with algebraic data types.
> Unfortunately, it's crap in HaXe because even though you can "add" methods
> such as size, head, tail, drop, concat, fold, map, filter, etc., you cannot
> unify across List and other collection types (such as Maps) which cannot be
> implemented using enums.
> So there's no way to both (1) represent List using an enum, and (2) create a
> unified collection library that allows some code to be agnostic with respect
> to what kind of collection they are receiving.
> Similarly, Stax uses Option to denote the presence/absence of a value:
>
> enum Option<T> {
>   Some(t: T);
>   None;
> }
>
> Enum is in fact a monad, and it would be great if code that can work on any
> monad can just accept a Monad<T>, but because it's impossible to abstract
> over enums (enums cannot implement interfaces!), I instead just have to
> duplicate tons of code for every enum and accept that code must be special
> cased depending on the kind of monad (enum or class based).
> The decision to disallow abstraction over enums results in much code
> duplication, and leaves enums impotent for any serious task; they are fit
> only for the simplest of use cases, and do not offer the power of, for
> example, Haskell's algebraic data types, which allow full abstraction via
> type classes.
> Regards,
> John A. De Goes
> Twitter: @jdegoes
> LinkedIn: http://linkedin.com/in/jdegoes
> On Dec 14, 2010, at 8:12 AM, Juraj Kirchheim wrote:
>
> On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
>
> Hi!
>
> What about extending the language to allow adding methods to enums?
>
> As with many other problems, simple composition solves this:
>
> class ABObject {
>   public var data(default, null):AB;
>   public function toString() : String {
>       return switch( data ) {
>           case A(a): "A(" + a.toString(); + ")";
>           case B(b,c): "B(" + b + c.toString() + ")";
>   }
> }
>
> Enums are not OO, as Nicolas put it.
> If OO is what you want, define an interface and transform every
> constructor into an implementing class and refactor switches made on
> the enum into the interface.
>
> Example:
>
>    enum Color {
>        grey( v : Int );
>        rgb( r : Int, g : Int, b : Int );
>    }
>    class Colors {
>        static function toInt( c : Color ) : Int {
>            return switch( c ) {
>                case grey(v): 0x010101 * v;
>                case rgb(r,g,b): (r << 16) | (g << 8) | b;
>            }
>        }
>    }
>
> Is transformed into
>
>   interface Color {
>      function toInt():Int;
>   }
>   class Grey implements Color {
>     //implementation
>   }
>   class RGB implements Color {
>     //implementation
>   }
>
> **That** is OO. Because data and logic are encapsulated into distinct,
> decantralized objects, while for enums data is defined in a central
> manner and logic can be completely decentralized, which is a different
> paradigm.
>
> I see how your proposition provides a certain kind of comfort, but it
> blurs the border between two orthogonal features and two very opposed
> approaches. It affects clarity and strictness, which I think are two
> core philosophies of haXe.
>
> greetz
> back2dos
>
> --
> haXe - an open source web programming language
> http://haxe.org
>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

John A. De Goes
In reply to this post by Juraj Kirchheim

In an object oriented language, if there exist some types which are not objects, then it's not possible to use interfaces to unify across them. Which means code duplication and special casing, or some other construct aside from an interface that can be used to abstract over the different type hierarchies (in Haskell it's a type class).

Every consistent, well-thought out language allows unification over all types to eliminate duplication and boilerplate. Even the current version of Java does this through auto-boxing of primitives.

Regards,

John A. De Goes
Twitter: @jdegoes
LinkedIn: http://linkedin.com/in/jdegoes

On Dec 16, 2010, at 11:48 AM, Juraj Kirchheim wrote:

> (Sorry, hit send accidentally).
> Yes, and virtually any other high level language allows abstraction
> over integers.
> haXe enums are primitive types. Full stop. Just because Sun thought
> "everything is an object" is a hip thing 15 years ago, this doesn't
> mean everything has to be an object.
> Everything is an object is an oversimplyfication. It is a restriction
> languages as C++ and Objective-C do not have.
> What you want can possibly be achieved with the suggested multitypes,
> but this weird mix, as suggested, really violates OO at its core.
>
> On Thu, Dec 16, 2010 at 7:43 PM, Juraj Kirchheim
> <[hidden email]> wrote:
>> Yes, and virtually any other high level language allows abstraction
>> over integers.
>> haXe enums are primitive types. Full stop. Just because Sun thought
>>
>> On Wed, Dec 15, 2010 at 5:49 PM, John A. De Goes <[hidden email]> wrote:
>>>
>>> You're completely wrong, of course.
>>> Every other high-level language having enums or enum-like data has a way to
>>> abstract across type hierarchies. Not so with HaXe enums.
>>> For example, I wanted to represent List as:
>>>
>>> enum List<T> {
>>>   Cons(head: T, tail: List<T>);
>>>   Nil;
>>> }
>>>
>>> This is the idiomatic representation with algebraic data types.
>>> Unfortunately, it's crap in HaXe because even though you can "add" methods
>>> such as size, head, tail, drop, concat, fold, map, filter, etc., you cannot
>>> unify across List and other collection types (such as Maps) which cannot be
>>> implemented using enums.
>>> So there's no way to both (1) represent List using an enum, and (2) create a
>>> unified collection library that allows some code to be agnostic with respect
>>> to what kind of collection they are receiving.
>>> Similarly, Stax uses Option to denote the presence/absence of a value:
>>>
>>> enum Option<T> {
>>>   Some(t: T);
>>>   None;
>>> }
>>>
>>> Enum is in fact a monad, and it would be great if code that can work on any
>>> monad can just accept a Monad<T>, but because it's impossible to abstract
>>> over enums (enums cannot implement interfaces!), I instead just have to
>>> duplicate tons of code for every enum and accept that code must be special
>>> cased depending on the kind of monad (enum or class based).
>>> The decision to disallow abstraction over enums results in much code
>>> duplication, and leaves enums impotent for any serious task; they are fit
>>> only for the simplest of use cases, and do not offer the power of, for
>>> example, Haskell's algebraic data types, which allow full abstraction via
>>> type classes.
>>> Regards,
>>> John A. De Goes
>>> Twitter: @jdegoes
>>> LinkedIn: http://linkedin.com/in/jdegoes
>>> On Dec 14, 2010, at 8:12 AM, Juraj Kirchheim wrote:
>>>
>>> On Mon, Dec 13, 2010 at 12:27 PM, Vag Vagoff <[hidden email]> wrote:
>>>
>>> Hi!
>>>
>>> What about extending the language to allow adding methods to enums?
>>>
>>> As with many other problems, simple composition solves this:
>>>
>>> class ABObject {
>>>   public var data(default, null):AB;
>>>   public function toString() : String {
>>>       return switch( data ) {
>>>           case A(a): "A(" + a.toString(); + ")";
>>>           case B(b,c): "B(" + b + c.toString() + ")";
>>>   }
>>> }
>>>
>>> Enums are not OO, as Nicolas put it.
>>> If OO is what you want, define an interface and transform every
>>> constructor into an implementing class and refactor switches made on
>>> the enum into the interface.
>>>
>>> Example:
>>>
>>>    enum Color {
>>>        grey( v : Int );
>>>        rgb( r : Int, g : Int, b : Int );
>>>    }
>>>    class Colors {
>>>        static function toInt( c : Color ) : Int {
>>>            return switch( c ) {
>>>                case grey(v): 0x010101 * v;
>>>                case rgb(r,g,b): (r << 16) | (g << 8) | b;
>>>            }
>>>        }
>>>    }
>>>
>>> Is transformed into
>>>
>>>   interface Color {
>>>      function toInt():Int;
>>>   }
>>>   class Grey implements Color {
>>>     //implementation
>>>   }
>>>   class RGB implements Color {
>>>     //implementation
>>>   }
>>>
>>> **That** is OO. Because data and logic are encapsulated into distinct,
>>> decantralized objects, while for enums data is defined in a central
>>> manner and logic can be completely decentralized, which is a different
>>> paradigm.
>>>
>>> I see how your proposition provides a certain kind of comfort, but it
>>> blurs the border between two orthogonal features and two very opposed
>>> approaches. It affects clarity and strictness, which I think are two
>>> core philosophies of haXe.
>>>
>>> greetz
>>> back2dos
>>>
>>> --
>>> haXe - an open source web programming language
>>> http://haxe.org
>>>
>>>
>>> --
>>> haXe - an open source web programming language
>>> http://haxe.org
>>>
>>
>
> --
> haXe - an open source web programming language
> http://haxe.org
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

Juraj Kirchheim
On Thu, Dec 16, 2010 at 8:33 PM, John A. De Goes <[hidden email]> wrote:
>
> In an object oriented language, if there exist some types which are not objects, then it's not possible to use interfaces to unify across them. Which means code duplication and special casing, or some other construct aside from an interface that can be used to abstract over the different type hierarchies (in Haskell it's a type class).
>
> Every consistent, well-thought out language allows unification over all types to eliminate duplication and boilerplate. Even the current version of Java does this through auto-boxing of primitives.

int is autoboxed to Integer, which is final. All classes dealing with
represantation of primitives are either abstract or final. You cannot
make a numeric primitive, that implements java.lang.Runnable (really
picked this one at random). In C# Int32 is a struct, so you cannot
extend it, so you have the same problem. In Objective-C and C++ there
is no autoboxing. Now you could say, all these languages are
inconsistent and poorly designed.

The everything-is-an-object-philosophy is flawed. Primitives as a
special type of value objects best illustrate this. Those are objects,
that by definition have no identity and are defined by the values they
store, while an actual object is defined by its identity and its
self-determined behaviour.

Putting primitives into boxes labeled "object", doesn't make things
object oriented.
In Ruby, you can go an overwrite how FixNum or any custom subclass
responds to /. This is nice, and far more consistent. It's what makes
Ruby so sexy. And so slow.

For a language to allow OOP, it needn't enforce it in every case. haXe
also allows certain aspects of FP and doesn't enforce them. IMHO,
rather than tucking object-stickers and methods onto things, that are
mere values, it would be a much better idea to make class instances
more object-ish, in the classic definition of the word. It would also
be nice to make proxying, composition and delegation easier. It would
be nice to have actual mixins. I think there is more to win when
trying to deepen individual features, than trying to unify them.

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Enum methods

John A. De Goes

Please read my e-mails before responding to them. I don't care if you consider integers or enums "objects". I only care that if I use both enum monads and class monads, I can define a Monad type to abstract over all of them so that code which works with all monads works across the type hierarchies. Without this, it is impossible to avoid code duplication and specialization per each type hierarchy.

The simplest way to support cross-type abstraction in HaXe is to allow enums to have methods (and implement interfaces). It's not the only way, but it does have the virtue of being consistent with Scala and Java.

Regards,

John A. De Goes
Twitter: @jdegoes
LinkedIn: http://linkedin.com/in/jdegoes

On Dec 16, 2010, at 3:54 PM, Juraj Kirchheim wrote:

> On Thu, Dec 16, 2010 at 8:33 PM, John A. De Goes <[hidden email]> wrote:
>>
>> In an object oriented language, if there exist some types which are not objects, then it's not possible to use interfaces to unify across them. Which means code duplication and special casing, or some other construct aside from an interface that can be used to abstract over the different type hierarchies (in Haskell it's a type class).
>>
>> Every consistent, well-thought out language allows unification over all types to eliminate duplication and boilerplate. Even the current version of Java does this through auto-boxing of primitives.
>
> int is autoboxed to Integer, which is final. All classes dealing with
> represantation of primitives are either abstract or final. You cannot
> make a numeric primitive, that implements java.lang.Runnable (really
> picked this one at random). In C# Int32 is a struct, so you cannot
> extend it, so you have the same problem. In Objective-C and C++ there
> is no autoboxing. Now you could say, all these languages are
> inconsistent and poorly designed.
>
> The everything-is-an-object-philosophy is flawed. Primitives as a
> special type of value objects best illustrate this. Those are objects,
> that by definition have no identity and are defined by the values they
> store, while an actual object is defined by its identity and its
> self-determined behaviour.
>
> Putting primitives into boxes labeled "object", doesn't make things
> object oriented.
> In Ruby, you can go an overwrite how FixNum or any custom subclass
> responds to /. This is nice, and far more consistent. It's what makes
> Ruby so sexy. And so slow.
>
> For a language to allow OOP, it needn't enforce it in every case. haXe
> also allows certain aspects of FP and doesn't enforce them. IMHO,
> rather than tucking object-stickers and methods onto things, that are
> mere values, it would be a much better idea to make class instances
> more object-ish, in the classic definition of the word. It would also
> be nice to make proxying, composition and delegation easier. It would
> be nice to have actual mixins. I think there is more to win when
> trying to deepen individual features, than trying to unify them.
>
> --
> haXe - an open source web programming language
> http://haxe.org
>


--
haXe - an open source web programming language
http://haxe.org