February 15

I think full sumtypes are probably usually overkill and I rarely use it; but I have some lib ideas that need... something

struct shape{
  int w,h;
  bool isCircle()=>h==-1;
  bool isSquare()=>w==h;
  bool isRect()=>h!=-1 && w!=h;
}
void drawCircle(shape s){
  assert(s.isCircle)
...

Classification could be pulled out from tag and it being a full union in the above example.

Radix sorts classify using a user defined function to then index an array of pointers to make a copy

fizzbuzz using ranges is kinda tricky, despite being computationally trivial, maintaining the control flow from classification while having access to the data is hard

etc.


so api wise...

classify: returns an int from the value

classmax: defines that max value classify may return(enum)

match: calls classify, swizzles the value to a collection of lamdas

etc.

what preexisting code plays with such ideas and how do they name their things?

6 days ago

On Saturday, 15 February 2025 at 19:49:59 UTC, monkyyy wrote:

code

import std;

struct nullable(T){
	T get_; alias get_ this;
	bool isnull=false;
	int classify()=>isnull;
	enum classmax=2;
	alias get(int i=0)=get_;
}

unittest{
	nullable!int foo;
}

template match(F...){
auto match(T)(T t){
	switch(t.classify){
		static foreach(I;0..T.classmax){
			case I: return F[I](t.get!I);
		}
	default: assert(0);
}}}

unittest{
	nullable!int foo;
	void bar(nullable!int i)=>i.match!((a){"real".writeln;},(a){"null".writeln;});
	bar(foo);
	int foobar(nullable!int i)=>i.match!(a=>1,a=>2);
	foobar(foo).writeln;
	foo.isnull=true;
	bar(foo);
	foobar(foo).writeln;
}

struct smallint{
	int i;
	int classify()=>i<=ubyte.max && i>=0;
	enum classmax=2;
	ubyte get(int i:1)()=>cast(ubyte)i;
	alias get(int i:0)=i;
}
unittest{
	foreach(i;[0,4,10,1000,1].map!(i=>smallint(i))){
		i.match!(a=>"error",a=>"fine").writeln;
	}}
union U{
	ubyte i;
	char c;
	float f;
}
struct tagunion{
	int classify;
	U u; alias u this;
	enum classmax=3;
	auto get(int i:0)()=>u.i;
	auto get(int i:1)()=>u.c;
	auto get(int i:2)()=>u.f;
}
unittest{
	tagunion foo;
	void bar(tagunion u){u.match!(writeln,writeln,writeln);}
	foo.i=3;
	bar(foo);
	foo.classify=1;
	foo.c='z';
	bar(foo);
	foo.classify=2;
	foo.f=13.37;
	bar(foo);
}