sumtype icon indicating copy to clipboard operation
sumtype copied to clipboard

railroad oirented programming

Open crazymonkyyy opened this issue 10 months ago • 6 comments

cough how open are you to pr's?

ranges+sumtypes need some work; I have some thoery and syntax test code, I think I can add a few functions to make your version better even if I dont care about all your safetyism goals

crazymonkyyy avatar Mar 09 '25 08:03 crazymonkyyy

I am open to both PRs and feature requests.

If this is intended to be a feature request, it would be helpful if you could describe the specific feature(s) you are requesting in more detail.

If you are just asking permission to submit a PR, then go ahead, and I'll close this issue as completed.

pbackus avatar Mar 09 '25 13:03 pbackus

Its a mix of both feature requests and offer to write code

Thinking in pictures from this guy: https://fsharpforfunandprofit.com/rop/

a range of sumtype is a row of train tracks

route - reordering and possibly combining the tracks tee - remove a track tap - call a function on one track (+ utility functions for sumtype its fairly barebones having only one function)


my last version of syntax tests had this code

enum maxsizeof(T...)=24;//todo impliment after standardizing some algorthims
struct tagunion(T...){
	ubyte[maxsizeof!T] data;
	ubyte classify;
	enum classmax=T.length;
	ref S intpertivecast(S)()=>*cast(S*)(&data);
	ref get(int I)()=>intpertivecast!(T[I]);
	//void set(int I)(T[I] a){intpertivecast!(T[I])=a;classify=I;}
	void get(int I)(T[I] a){intpertivecast!(T[I])=a;classify=I;}
}

The striking differences are the get!T vs get!int and duplicate types are innately working.

I think your getByIndex!int would need to be public

it also had a helper function for use case of duplicate types

auto part(alias F,int max,T)(T t){
	tagunion!(repeat!(max,T)) o;
	o.get!0=t;
	o.classify=cast(ubyte)F(t);
	return o;
}

if sumtype stays innately undupicated I believe you could make auto tempature = (37.2).part!(a=>0,"F","C","K")=> sumtype of temperature but would be much longer then 5 lines.

etc.

syntax test code code for context:

railroad3.d.txt

crazymonkyyy avatar Mar 09 '25 18:03 crazymonkyyy

I'm afraid I can't make heads or tails of these examples.

pbackus avatar Mar 11 '25 01:03 pbackus

Suppose your parsing some numbers

auto attemptparse(string s){
  alias Output=Sumtype!(int,float,string);
  if(canparseint(s){
    ...
    return Output(int(...));
  }
  if(canparsefloat(s)){...}
  return Output(s);
}

You get your range File(...).byLineCopy.map!attemptparse

those strings are errors, that you may want to just clean up

.tee!((string s){writeln("WARN: failed to parse",s);}

you now have a range of Sumtype!(int,float);

crazymonkyyy avatar Mar 11 '25 02:03 crazymonkyyy

Ok, I see. It sounds like tee is sort of a combination of match, filter, and map—it filters out the SumType values that match the handler(s) passed to it, and then maps the remaining SumType values to a new kind of SumType that excludes the type(s) that were matched.

Personally, I don't think this function would be a good addition to the sumtype package. Because it does so many different things at once, it is only useful in the specific use-cases where all of those things need to be done. If I'm going to add new functions to sumtype, I would prefer them to do only one thing and be applicable to a wide variety of use-cases. The recently-added has, get, and tryGet functions are a good example.

pbackus avatar Mar 11 '25 02:03 pbackus

I think your viewing the goal wrong; you expand out the cases then you handle them, you may need to delay the logic for some reason in some ugly range function, then your cleaning up error states until you have the sumtypes you want. Tee is simple because its just disapearing the error state.


For your type based syntax I think route would look like Sumtype!(int,float).route!((float f)=>f.to!int).stringof==int I cant imagine making that simplier

crazymonkyyy avatar Mar 11 '25 03:03 crazymonkyyy