Skip to content

Commit

Permalink
Explain variadic runtime mixed with comptime parameters, add curry, a…
Browse files Browse the repository at this point in the history
…djoin, compose, memoize, and bind, remove unnecessary HResult specification
  • Loading branch information
cetio committed May 7, 2024
1 parent c1d0b35 commit 8db1ce9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 36 deletions.
14 changes: 14 additions & 0 deletions spec/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,20 @@ foo(1, 2);
foo([1, 2]);
```

Variadics may appear only once in a signature, and must be the very last declaration, however this rule is slightly bypassed with generics where variadics may appear twice if one of the variadics is used as the type of a runtime argument, like in this example:

```
void foo(A..., B...)(B b)
{
// ...
}
// It is impossible to set B explicitly, but this is allowed because it can be set implicitly based on the arguments passed.
// A = [int, string]
// B = [int, int]
foo!(int, string)(1, 2);
```

Parameters with values set after their declaration will have optional values set by default, these, like variadic parameters, must be the last parameters in the function signature.

##### Arguments
Expand Down
59 changes: 59 additions & 0 deletions std/functional.fn
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module std.functional;

import std.traits;

auto curry(alias F, ARGS...)(ref ARGS args)
{
if (args.length != F.parameters.length)
return = F.returnof function() f = ((F.parameters)[ARGS.length..$] _args) { return = F(args, _args); };
else
return = F.returnof function((F.parameters)[ARGS.length..$]) f = () { return = F(args); };
}

auto adjoin(FS...)()
if (FS.length >= 1)
{
alias[] R;
foreach (F; FS)
R ~= F.returnof;

return = R function()
{
foreach (i, F; FS)
return[i] = F();
};
}

FS[$-1].returnof compose(FS...)(FS[0].parameters args)
if (FS.length >= 1)
{
alias[] R;
foreach (F; FS)
R ~= F.returnof;

return = FS[$-1].returnof function()
{
R stor;
stor[0] = FS[0](args);

if (FS.length > 1)
foreach (i, F; FS[1..$])
stor[i] = F(stor[i - 1]);

return = stor[$-1];
};
}

F.returnof memoize(alias F)(F.parameters args)
{
static F.returnof? cache;
if (cache == void)
cache = F(args);
return = cache;
}

F.returnof function() bind(alias F, T)(T val)
{
foreach (field; val.fields)
return = curry!F(field.value);
}
72 changes: 36 additions & 36 deletions std/hresult.fn
Original file line number Diff line number Diff line change
Expand Up @@ -43,40 +43,40 @@ public const tagged HResult : ^int
RPC_E_NOT_REGISTERED = 0x80010103;
RPC_E_DUPLICATE_NAME = 0x8001012C;

bool OK() => this is HResult.S_OK;
bool NOTOK() => this !is HResult.S_OK;
bool FALSE() => this is HResult.S_FALSE;
bool ABORT() => this is HResult.E_ABORT;
bool FAIL() => this is HResult.E_FAIL;
bool NOINTERFACE() => this is HResult.E_NOINTERFACE;
bool NOTIMPL() => this is HResult.E_NOTIMPL;
bool POINTER() => this is HResult.E_POINTER;
bool UNEXPECTED() => this is HResult.E_UNEXPECTED;
bool ACCESSDENIED() => this is HResult.E_ACCESSDENIED;
bool HANDLE() => this is HResult.E_HANDLE;
bool INVALIDARG() => this is HResult.E_INVALIDARG;
bool OUTOFMEMORY() => this is HResult.E_OUTOFMEMORY;
bool BADIMAGEFORMAT() => this is HResult.E_BADIMAGEFORMAT;
bool BOUNDS() => this is HResult.E_BOUNDS;
bool PENDING() => this is HResult.E_PENDING;
bool NOT_SET() => this is HResult.E_NOT_SET;
bool NOTINITIALIZED() => this is HResult.CO_E_NOTINITIALIZED;
bool ALREADYINITIALIZED() => this is HResult.CO_E_ALREADYINITIALIZED;
bool NOTSUPPORTED() => this is HResult.CO_E_NOTSUPPORTED;
bool CLASSSTRING() => this is HResult.CO_E_CLASSSTRING;
bool APPNOTFOUND() => this is HResult.CO_E_APPNOTFOUND;
bool OBJECTNOTCONNECTED() => this is HResult.CO_E_OBJECTNOTCONNECTED;
bool BADINDEX() => this is HResult.DISP_E_BADINDEX;
bool OVERFLOW() => this is HResult.DISP_E_OVERFLOW;
bool TYPEMISMATCH() => this is HResult.DISP_E_TYPEMISMATCH;
bool PARAMNOTFOUND() => this is HResult.DISP_E_PARAMNOTFOUND;
bool UNKNOWNINTERFACE() => this is HResult.DISP_E_UNKNOWNINTERFACE;
bool CHANGEDMODE() => this is HResult.RPC_E_CHANGED_MODE;
bool TOOLATE() => this is HResult.RPC_E_TOO_LATE;
bool INVALIDMETHOD() => this is HResult.RPC_E_INVALIDMETHOD;
bool DISCONNECTED() => this is HResult.RPC_E_DISCONNECTED;
bool SERVERFAULT() => this is HResult.RPC_E_SERVERFAULT;
bool TIMEOUT() => this is HResult.RPC_E_TIMEOUT;
bool NOTREGISTERED() => this is HResult.RPC_E_NOT_REGISTERED;
bool DUPLICATENAME() => this is HResult.RPC_E_DUPLICATE_NAME;
bool OK() => this is S_OK;
bool NOTOK() => this !is S_OK;
bool FALSE() => this is S_FALSE;
bool ABORT() => this is E_ABORT;
bool FAIL() => this is E_FAIL;
bool NOINTERFACE() => this is E_NOINTERFACE;
bool NOTIMPL() => this is E_NOTIMPL;
bool POINTER() => this is E_POINTER;
bool UNEXPECTED() => this is E_UNEXPECTED;
bool ACCESSDENIED() => this is E_ACCESSDENIED;
bool HANDLE() => this is E_HANDLE;
bool INVALIDARG() => this is E_INVALIDARG;
bool OUTOFMEMORY() => this is E_OUTOFMEMORY;
bool BADIMAGEFORMAT() => this is E_BADIMAGEFORMAT;
bool BOUNDS() => this is E_BOUNDS;
bool PENDING() => this is E_PENDING;
bool NOT_SET() => this is E_NOT_SET;
bool NOTINITIALIZED() => this is CO_E_NOTINITIALIZED;
bool ALREADYINITIALIZED() => this is CO_E_ALREADYINITIALIZED;
bool NOTSUPPORTED() => this is CO_E_NOTSUPPORTED;
bool CLASSSTRING() => this is CO_E_CLASSSTRING;
bool APPNOTFOUND() => this is CO_E_APPNOTFOUND;
bool OBJECTNOTCONNECTED() => this is CO_E_OBJECTNOTCONNECTED;
bool BADINDEX() => this is DISP_E_BADINDEX;
bool OVERFLOW() => this is DISP_E_OVERFLOW;
bool TYPEMISMATCH() => this is DISP_E_TYPEMISMATCH;
bool PARAMNOTFOUND() => this is DISP_E_PARAMNOTFOUND;
bool UNKNOWNINTERFACE() => this is DISP_E_UNKNOWNINTERFACE;
bool CHANGEDMODE() => this is RPC_E_CHANGED_MODE;
bool TOOLATE() => this is RPC_E_TOO_LATE;
bool INVALIDMETHOD() => this is RPC_E_INVALIDMETHOD;
bool DISCONNECTED() => this is RPC_E_DISCONNECTED;
bool SERVERFAULT() => this is RPC_E_SERVERFAULT;
bool TIMEOUT() => this is RPC_E_TIMEOUT;
bool NOTREGISTERED() => this is RPC_E_NOT_REGISTERED;
bool DUPLICATENAME() => this is RPC_E_DUPLICATE_NAME;
}

0 comments on commit 8db1ce9

Please sign in to comment.