Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Generic Impls: Thinking Out Loud


Go has something somewhat like that, in Go interfaces.
https://gobyexample.com/interfaces

You'd write something along the lines of:

type hashable interface {
  hash() int32
}

Then to implement it for some defined type foo, you'd write:

func (f foo) hash() int32 {
  var hash int32;
   /* do something */
  return hash
}

A type may implement any number of interfaces, but Go doesn't let you do
interface inheritance or anything like that.

--Stephen

On Fri, Dec 25, 2015 at 9:11 AM, Ryan Gonzalez <rymg19@xxxxxxxxx> wrote:

>
>
> On December 24, 2015 9:49:09 PM CST, Ori Bernstein <ori@xxxxxxxxxxxxxx>
> wrote:
> >So, poking around code, I found myself wanting to be able to write
> >something
> >along the lines of:
> >
> >       trait hashable @a =
> >               hash    : (@a -> int32)
> >       ;;
> >
> >
> >       /* hash any type shallowly: hash &a */
> >       impl hashable @a# =
> >               hash    = {val
> >                       -> hashbytes(val[:sizeof(@a)])
> >               }
> >       ;;
> >
> >       /* hash any slice using its appropriate trait */
> >       impl hashable @a[:]
> >               hash = {sl
> >                       var h
> >
> >                       h = 0
> >                       for v in sl
> >                               h ^= hash(&v)
> >                       ;;
> >                       -> h
> >               }
> >       ;;
> >
> >       /* ...and similar... */
> >
> >This would also allow useful things like:
> >
> >       type enumerated(@a::iterable) =
> >               idx     : std.size
> >               it      : @a
> >       ;;
> >
> >       impl iterable enumerated(@a::iterable) -> (@a, std.size)
> >               __iternext__ = {enum, out
> >                       var val
> >                       if __iternext__(&enum.it, &val)
> >                               -> (val, it.idx++)
> >                       else
> >                               -> false
> >                       ;;
> >               }
> >               ...
> >       }
> >
> >
> >However, this seems like it would open up.. uh.. interesting choices.
> >I'd rather avoid going down the complex C++ path, so it makes me uneasy
> >when I realize I'd have to start defining rules for a "best match" for
> >a trait implementation :/
> >
> >And things like
> >
> >       impl foo (@a, int) = ...;;
> >       impl foo (int, @a) = ...;;
> >
> >exist to make it more iteresting.
> >
> >Other than C++ with its SFINAE, are there languages out there that have
> >a good model for doing this?
>
> I think Haskell lets you do this, although I haven't programmed in it for
> a few months. I think it lets you do something like:
>
> class Hashable a where
>   hash :: a -> Int
>
> -- Assume Ptr a is syntax for pointers or something...
> instance Hashable (Ptr a) where
>   hash = hashbytes
>
> -- And assume this is slice syntax.
> instance (Hashable a) => Hashable (Slice a) where
>   hash x = -- Hash the slice x.
>
>
> Since Haskell is quite *ahem* math-y, I'm pretty sure there's something
> smart behind how this works.
>
> I think it just puts all the implementations on the same level. If more
> than one matches, it's always an error. No ordered rules like C++.
> --
> Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.
>
>

References:
Generic Impls: Thinking Out LoudOri Bernstein <ori@xxxxxxxxxxxxxx>
Re: Generic Impls: Thinking Out LoudRyan Gonzalez <rymg19@xxxxxxxxx>