Stack based array language (Uiua)

Timon Gehr timon.gehr at gmx.ch
Wed Oct 4 08:36:39 UTC 2023


On 9/30/23 18:55, monkyyy wrote:
> How could you make a small project in d that hacks together a stack meta 
> layer on top of ranges?

Generates a lot of template bloat, but you can do this:

```d
import std;

auto dupZeroes(R,T...)(Tuple!(R,T) stack){
     return stack
         .dup
         .dup
         .push(0)
         .equals
         .push(1)
         .add
         .keep
         .flip
         .len
         .take
         ;

}

void main(){
     tuple()
         .push([1,0,2,3,0,4,5,0])
         .dupZeroes
         .push([1,2,3])
         .dupZeroes
         .push([0,3,0,4,5])
         .dupZeroes
         .writeln;
}

alias equals=binary!((a,b)=>a==b);
alias add=binary!((a,b)=>a+b);
alias keep=binary!((a,b)=>zip(a,b).mapArgs!((x,y)=>repeat(x,y)).joiner);
alias len=unary!(x=>x.length);
alias take=std.range.take;
alias take=binary!((a,b)=>a.take(b));

template mapArgs(alias f){ auto mapArgs(R)(R r)=>r.map!(x=>f(x.expand)); }

struct Tuple(T...){
     T expand;
     alias expand this;
     string toString(){
         string r;
         foreach(i,ref x;expand){
             if(i) r~="\n";
             r~=text(x);
         }
         return r;
     }
}
auto tuple(T...)(T args)=>Tuple!T(forward!args);

auto dup(S,T...)(Tuple!(S,T) stack)=>tuple(stack.expand,stack[$-1]);
auto push(S,T...)(Tuple!T stack,S head)=>tuple(stack.expand,head);
auto flip(R,S,T...)(Tuple!(R,S,T) 
stack)=>tuple(stack[0..$-2],stack[$-1],stack[$-2]);
template apply(alias f,int nargs=-1){
     auto apply(S,T...)(Tuple!(S,T) stack){
         static if(nargs==-1){
             static if(__traits(compiles,f(stack.expand).expand)) return 
tuple(f(stack.expand).expand);
             else static if(__traits(compiles,f(stack.expand))) return 
tuple(f(stack.expand));
             else return tuple(stack[0],apply(tuple(stack[1..$])).expand);
         }else{
             static if(__traits(compiles,f(stack[$-nargs..$]).expand)) 
return tuple(stack[0..$-nargs],f(stack[$-nargs..$]).expand);
             else return tuple(stack[0..$-nargs],f(stack[$-nargs..$]));
         }
     }
}

alias broadcast1(alias f)=(x){
     static if(__traits(compiles,f(x))) return f(x);
     else static if(__traits(compiles,x.map!broadcast1)) return 
x.map!broadcast1;
     else static assert(0,f(x));
};
alias unary(alias f)=apply!(broadcast1!f,1);
alias broadcast2(alias f)=(x,y){
     static if(__traits(compiles,f(x,y))) return f(x,y);
     else static if(__traits(compiles,x.map!(a=>broadcast2(a,y)))) 
return x.map!(a=>broadcast2(a,y));
     else static if(__traits(compiles,y.map!(b=>broadcast2(x,b)))) 
return y.map!(b=>broadcast2(x,b));
     else static 
if(__traits(compiles,zip(x,y).mapArgs!((a,b)=>broadcast2(a,b)))) return 
zip(x,y).mapArgs!((a,b)=>broadcast2(a,b));
     else static assert(0,f(x,y));
};
alias binary(alias f)=apply!(broadcast2!f,2);
```


More information about the Digitalmars-d mailing list