(Shiver me timbers! There be slides this year!)
File written: May 29, 2015, 9:38 AM, MDT
In the beginning, Computer created the registers and the RAM.
And the memory was without types, yea, even void*.
mov EAX, 65;
// Does EAX hold cast(char) 'A'?
// Or cast(int) 65?
// Or cast(MyStruct*) 0x41?
// Nobody knows. And the hardware doesn't care.
And Computer said, Let there be types: and there were types.
And Computer saw the types, that they were good: and Computer divided the compile-time from the run-time.
(Genesis 1:1-4)| Static (Compile-time checked) | |||
|---|---|---|---|
| C | C++, Haskell | ||
| Weak (Implicitly Coerced) |
Strong (Mismatches as errors) |
||
| Javascript, PHP | Ruby, Python, Java (sort of) | ||
| Dynamic (runtime tagged) | |||
Raw memory is untyped and also not quite coerced; it is reinterpreted which is a bit different.
LOL GENERIC PROGRAMMING CONCEPTS ABOVE
~Too Meta~Er... wrong James...
// this is valid D code!
var a = 10;
var b = "20";
var c = a + b;
var d = json!q{ "foo": { "bar": 10.2 } };
writeln(d.foo); // {"bar":10.2}
d.foo.bar = (var a) => a ~ b;
writeln(d.foo.bar()("hello! "));
struct MyType {
enum Holding {Int, String}
Holding type;
union {
int Int;
string String;
}
}
TypeInfo type;
union {
void* data;
ubyte[MAX_SIZE] small_type_optimization;
}
They all go well with milk!
public var opBinary(string op, T)(T t) {
var n;
if(payloadType() == Type.Object) {
var* operator = this._payload._object._peekMember("opBinary", true);
if(operator !is null && operator._type == Type.Function) {
return operator.call(this, op, t);
}
}
return _op!(n, this, op, T)(t);
}
public var opBinaryRight(string op, T)(T s) {
return var(s).opBinary!op(this);
}
Variant opBinary(string op)(T rhs) { return Variant(mixin("this.get!T" ~ op ~ "rhs)); }
} else static if(isCallable!T) {
this._type = Type.Function;
static if(is(T == typeof(this._payload._function))) {
this._payload._function = t;
} else
this._payload._function = delegate var(var _this, var[] args) {
var ret;
ParameterTypeTuple!T fargs;
foreach(idx, a; fargs) {
if(idx == args.length)
break;
cast(Unqual!(typeof(a))) fargs[idx] = args[idx].get!(typeof(a));
}
static if(is(ReturnType!t == void)) {
t(fargs);
} else {
ret = t(fargs);
}
return ret;
};
// and also wrapped native classes, automatically
WrappedNativeObject wrapNativeObject(Class)(Class obj) if(is(Class == class)) {
return new class WrappedNativeObject {
override Object getObject() {
return obj;
}
this() {
wrappedType = typeid(obj);
// wrap the other methods
// and wrap members as scriptable properties
foreach(memberName; __traits(allMembers, Class)) {
static if(is(typeof(__traits(getMember, obj, memberName)) type))
static if(is(typeof(__traits(getMember, obj, memberName)))) {
static if(is(type == function)) {
_properties[memberName] = &__traits(getMember, obj, memberName);
} else {
// if it has a type but is not a function, it is prolly a member
_properties[memberName] = new PropertyPrototype(
() => var(__traits(getMember, obj, memberName)),
(var v) {
static if(memberName == "handleCharEvent") {
import std.stdio; writeln("setting ", memberName, " to ", v.get!type.ptr);
}
__traits(getMember, obj, memberName) = v.get!(type);
});
}
}
}
}
};
}
You can convert foo.bar to foo["bar"] to punt it to runtime
var[string] properties;
var opDispatch(string member)() { return properties[member]; }
else static if(isDelegate!T) {
// making a local copy because otherwise the delegate might refer to a struct on the stack and get corrupted later or something
auto func = this._payload._function;
// the static helper lets me pass specific variables to the closure
static T helper(typeof(func) func) {
return delegate ReturnType!T (ParameterTypeTuple!T args) {
var[] arr;
foreach(arg; args)
arr ~= var(arg);
var ret = func(var(null), arr);
static if(is(ReturnType!T == void))
return;
else
return ret.get!(ReturnType!T);
};
}
return helper(func);
ref var thing() { return *( new var(null) ); }
This is garbage. But it works!
Contrast my usage of reflection with the protocol generation use - this is kinda needed here, can't be reasonably done ahead of time. We take a compile time hit, but it enables new stuff.
Static types are great for generation; none of this dynamic niceness would be really possible without it! Also rox for form generation etc btw.
class CastExpression : Expression {
string type;
Expression e1;
override string toString() {
return "cast(" ~ type ~ ") " ~ e1.toString();
}
override InterpretResult interpret(PrototypeObject sc) {
var n = e1.interpret(sc).value;
foreach(possibleType; CtList!("int", "long", "float", "double", "real", "char", "dchar", "string", "int[]", "string[]", "float[]")) {
if(type == possibleType)
n = mixin("cast(" ~ possibleType ~ ") n");
}
return InterpretResult(n, sc);
}
}
<
Regular struct cons is explicit: SName(some_arg).
void func(var a) { }
func(null); // can this implicitly make func(var(null)?)
func(10); // func(var(10)) implicitly?
C++ can do this. D sucks.
Useful outside dynamic types: what about library array replacements taking null? BigInt taking int?
Will it mess up overloading?
Use this sparingly, so saith the Computer. Even laziness isn't a good justification here!
void func(var a) {}
dycall!func(null); // dycall template wraps args
Doable, but not quite a drop-in replacement for language built-ins
d rox
var v = 10;
int a = v;
C++ can do this. D sucks.
var v = 10;
auto a = v.get!int;
Whereas we are supposed to use this sparingly, I think this is nice. auto rox enough, explicit movement back is good.
Callable prop() {}
prop(); // should call Callable
Please don't blab able optional parens, this is all I care about, leave the rest the same.
var globals = var.emptyObject;
globals.loadJsonFile = delegate var(string name) {
import std.file;
return var.fromJson(readText(name));
};
globals.saveJsonFile = delegate var(string name, var obj) {
import std.file;
write(name, obj.toJson());
return obj;
};
// wrapping my http2.d was easy too!
globals["get"] = delegate var(string path) {
auto request = client.navigateTo(Uri(path));
request.send();
return var(request.waitForCompletion());
};
writeln(interpret(line, globals));
errr out of time to make more slides, WE'LL DO IT LIVE!!!!!!!!!