Skip to content

Instantly share code, notes, and snippets.

@msullivan
Created July 13, 2012 00:09
Show Gist options
  • Save msullivan/3101979 to your computer and use it in GitHub Desktop.
Save msullivan/3101979 to your computer and use it in GitHub Desktop.
thoughts about vec construction and static fns
/*
Currently, all trait methods must take an implicit self parameter,
which is limiting in a lot of cases.
I propose that we add a notion of "static" trait methods (although I
don't really like that name). These are simply trait functions that do
not take a self parameter. These functions would be called like
regular functions, and the names would live in the module where the
trait is declared.
Nothing too tricky needs to be done to typecheck them or resolve them
to instances. They can be given parametric types, which will be
handled by existing infrastructure for typechecking functions that are
parametric over traits.
There are lots of places where this would be useful: basically
whenever an object needs to be created, and not just modified or
inspected.
*/
// Here are some examples of things:
// (The syntax I use for declaring them does not necessarily represent
// an actual proposal; the rest I stand by.)
trait read {
// returns the element we managed to parse, if we succeeded,
// and the rest of the string
static fn readPiece(s: str) -> (option<self>, str);
}
impl of read for int {
static fn readPiece(s: str) -> (option<int>, str) {
...
}
}
// And then a useful function in terms of it:
fn read<T: read>(s: str) -> T {
let (opt, rest) = readPiece(s);
alt opt {
some(x) if rest.len() == 0 { x }
_ { fail "parse failed" }
}
}
/*
There are lots of other places where this sort of thing would be
useful (many of these are inspired by base Haskell typeclasses):
- An enumeration typeclass, that allows conversion between enum
values and integers
- A numeric typeclass, that among other things allows constructing
a value from an integer. (pcwalton has wanted this for a while)
- A bounded typeclass, that can give you the minimum and maximum
values of a type
- A monoid typeclass, representing a type with a associative binary
operation and an identity element
- A sequence builder typeclass, that allows constructing new
~[]s, @[]s, lists, dlists, dvecs, sets, etc
*/
// An example of how the last one could work
trait buildable<A> {
// construct takes a function that will construct the vector.
// the `build` function will be passed as an argument a function
// to push elements onto the sequence being constructed.
// This interface allows constructing hiding the imperative
// construction of immutable sequences like @[]s.
static fn construct(build: fn(push: fn(A))) -> self;
}
// Some code that could use that, then:
fn seq_range<BT: buildable<uint>>(lo: uint, hi: uint) -> BT {
do construct() |push| {
for range(lo, hi) |i| {
push(i);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment