digitalmars.D - with and checked with expression?
ive read some discussions about some library solution for the ?.
operator,
has there been anything added to phobos?
wouldnt a checked with expression be a more general/longer form
of the ?. operator?
A with expression not only allows you to do unchecked/checked
access to members but to any operation you can do on the type,
it allows method/statement cascading so that you dont have to
return this from methods,
thereby you can combine it with function chaining without
breaking the cascading,
and it can also be used to wrap any statement to integrate them
into a function chain.
some example syntax:
aggregate types, returns its input
T t = T #aliasName { }; // works with any type, can use
aliasName to refer to the input like self/this, returns its input
RetType t = T #aliasName, RetType varName { }; // same as
above but can change the return type
// extention for the above, checks the input before executing
the block,
// if input is null/false the block does'nt get executed the
return value will be null/T.init/RetType.init
// optionally
would work like the statement expression
// mentioned in the kill the
comma operator thread, no input no output and allways runs block
// for single operations, the short null checked version is
less verbose
t?.foo = 5; // if t is null no assignment happens,
t.child = s?.child; // if s is null, t.child will be null,
typeof(t.child) ret{ ret = child;};
t?.child = s?.child?; // if t is null no assignment, if s or
s.child is null, t.child will be null,
// same as if(t) t.child = (s && s.child)? s.child : null; or
-----------------------------------------
some examples:
// using it with aggregate types
struct Foo{ string name; int val; }
class Bar{ string name; int val; }
{
import std.string : capitalize;
name = someName.capitalize;
val = 5;
}.writeln;
auto foo = Foo()#n{ name = "Foo"; val = 5; n.writeln; };
val = 30; };
// some other random uses
"test"#n{ import std.string; n.capitalize; }.writeln;
66#n, string ret{ import std.conv; ret = n.to!string; }.foo();
// writes the return value of someFun
someFun()#n{ n == 5? doSomething() :
n == 6? doSomethingElse() : null; }.writeln;
// writes five or six or no match
someFun()#n, string ret{ ret = n == 5? "five" :
n == 6? "six" : "no match";
}.writeln;
auto res = someFun.someOtherFun #n{ foreach(i; 0 .. n)
i.writeln; }.fun(6) #n{ n.writeln; };
//void fun(string name, int val, string, int);
param3 = 66; val = 2; }();
name = "test";
param2 = "some string";
param3 = 66;
val = 2;
};
wrappedFun.param0 = "Test";
wrappedFun.param2 = "some other string";
wrappedFun.val = 70;
wrappedFun();
// if(c.foo) c.foo.x = 55;
c.foo?.x = 55;
// if(someClass && someClass.child && someClass.child.child &&
// someOtherClass && someOtherClass.child &&
someOtherClass.child.child)
// { someClass.child.child.x = someOtherClass.child.child.x *
2; }
someClass?.child?.child?.x = someOtherClass?.child?.child?.x *
2;
lhs.x = rhs.x * 2;
};};};};};};
//if(someClass) with(someClass){
// x = 5; x.writeln;
// if(child) with(child){
// x = 6; x.writeln;
// alias lhs = child;
// if(child) with(child){
// if(someOtherClass) with(someOtherClass){
// x = 10; x.writeln;
// if(child) with(child){
// x = 59; x.writeln;
// if(child) with(child){
// lhs.x = x * 2;
// x = 44; x.writeln;
//} } } } } }
// same as above
}; }; }; }; }; };
// empty with expression, when you dont need a input and
output basically just a scope as a expression
{}
here some templates which implement parts of the above behavior
import std.functional : unaryFun;
auto then(alias fun, T)(T type) if(is(typeof(unaryFun!fun)))
{
import std.traits : ReturnType;
static if(is(ReturnType!(fun!T) == void))
{
fun(type);
return type;
}
else
{
return fun(type);
}
}
auto checkThen(alias fun, T)(T type)
if(is(typeof(unaryFun!fun)))
{
import std.traits : ReturnType, isFloatingPoint;
static if(is(ReturnType!(fun!T) == void))
{
static if(isFloatingPoint!T)
{ import std.math : isNaN;
if(type.isNaN) return type;
}
if(type) fun(type);
return type;
}
else
{
static if(isFloatingPoint!T)
{ import std.math : isNaN;
if(type.isNaN) return ReturnType!(fun!T).init;
}
return type? fun(type) : ReturnType!(fun!T).init;
}
}
example comparing the above templates and with expression:
original example from dlangui using mostly dml:
https://github.com/buggins/dlangui/blob/master/examples/helloworld/src/helloworld.d
with expression: https://dpaste.dzfl.pl/15f767d91212
templates: https://dpaste.dzfl.pl/5648204131c8
would something like this be usefull?
May 24 2016
On Tuesday, 24 May 2016 at 19:03:11 UTC, ArturG wrote:would something like this be usefull?A general word of advice - try to keep your post short & concise. It is more likely to get replies then. Yes it would be to me, but I am not sure whether it would justify it? For the expression?, imho it is very useful - existence checks are very common. I know that at least ruby and CoffeeScript have it. Do you know more?
May 24 2016
On Wednesday, 25 May 2016 at 00:36:04 UTC, Seb wrote:On Tuesday, 24 May 2016 at 19:03:11 UTC, ArturG wrote:Yes i might have used to many examples, should have used dpaste for all of them.would something like this be usefull?A general word of advice - try to keep your post short & concise. It is more likely to get replies then.Yes it would be to me, but I am not sure whether it would there use it?The syntax is of course up for debate, but similar to the with statement and others it creates its own scope so it should'nt be and exception and also use the {}. its optional parameters and it's a easy to reach single symbol which isnt ambigius with other D symbols. We cant use the syntax from freatures which provide similar functionality from other languages[1], because they use existing D syntax and are'nt as flexible as the with expression/statement. D already has similar syntax for struct initialiser and anonymous classes and as it can be chained it also kinda behaves like a eagerly called function/delegate. [1] https://en.wikipedia.org/wiki/Method_cascadingFor the expression?, imho it is very useful - existence checks are very common. I know that at least ruby and CoffeeScript have it. Do you know more?checked opCall which i didnt want to propose because it can be done with the with expression.
May 25 2016








ArturG <var.spool.mail700 gmail.com>