Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using dynamic typing in D, a statically typed language

I was implementing a dynamic typing library for D when I ran across an interesting problem.

Right now, I've succeeded in making a function called dynamic() which returns a dynamic version of an object.

For example:

import std.stdio, std.dynamic.core;

class Foo
{
    string bar(string a) { return a ~ "OMG"; }
    int opUnary(string s)() if (s == "-") { return 0; }
}

void main(string[] argv)
{
    Dynamic d = dynamic(new Foo());
    Dynamic result = d.bar("hi");
    writeln(result);  // Uh-oh
}

The problem I've run across is the fact that writeln tries to use compile-time reflection to figure out how to treat result.

What's the first thing it tries? isInputRange!(typeof(result))

The trouble is, it returns true! Why? Because I have to assume that all members which it needs exist, unless I can prove otherwise at run time -- which is too late. So the program tries to call front, popFront, and empty on result, crashing my program.

I can't think of a way to fix this. Does anyone have an idea?

like image 251
user541686 Avatar asked Aug 18 '11 05:08

user541686


People also ask

Where would you use a dynamically typed language over a statically typed language?

A language is dynamically typed if the type is associated with run-time values, and not named variables/fields/etc. This means that you as a programmer can write a little quicker because you do not have to specify types every time (unless using a statically-typed language with type inference).

What is difference between dynamically typed and statically typed?

First, dynamically-typed languages perform type checking at runtime, while statically typed languages perform type checking at compile time.

What is statically typed and dynamically typed languages give examples?

Statically typed languages perform type checking at compile-time, while dynamically-typed languages perform type checking at run-time. Statically-typed languages require you to declare the data types of your variables before you use them, while dynamically-typed languages do not.

What programming language that is dynamic in typing?

Conversely, in dynamically typed languages, type checking takes place at runtime or execution time. This means that variables are checked against types only when the program is executing. Some examples of programming languages that belong to this category are Python, JavaScript, Lisp, PHP, Ruby, Perl, Lua, and Tcl.


3 Answers

You are trying to make two fundamentally different concepts work together, namely templates and dynamic typing. Templates rely very much on static typing, isInputRange works by checking which attributes or methods a type has. Your dynamic type is treated as having every attribute or method at compile time, ergo it is treated as fulfilling every static duck-typing interface. Therefore, to make Dynamic work in a statically typed environment, you have to provide more static information at some places.

Some solutions I can see:

  1. provide your own dynamically typed implementations for heavily used functions. The whole problem you are having is caused by the fact that you are trying to use generic functions that assume static typing with dynamic types.

  2. explicitly make dynamic a range of char, and care for the conversion to string of the underlying data yourself. (You'd have to have a custom toString method anyways if the isInputRange issue would not exist, because otherwise its result would again be of Dynamic type). This would probably make writeln(d); work.

  3. provide wrappers for dynamic that allow you to pass dynamic types into various templated functions. (Those would just exhibit a static interface and forward all calls to Dynamic).

Eg:

Dynamic d;
// wrap d to turn it into a compile-time input range (but NOT eg a forward range)
Dynamic d2=dynamic(map!q{a*2}(dynInputRange(d))); 
// profit

4 . Add a member template to Dynamic, which allows to statically disable some member function names.

Eg:

static assert(!isForwardRange!(typeof(d.without!"save")));
like image 73
tgehr Avatar answered Nov 09 '22 05:11

tgehr


what is wrong with using std.variant which implements all you need for dynamic typing (along with quite a bit of syntactic sugar)

like image 28
ratchet freak Avatar answered Nov 09 '22 07:11

ratchet freak


Could you provide an overload for isInputRange? Something like this (note that I haven't looked at the implementation of isInputRange):

template isInputRange(T : Dynamic) {
    enum isInputRange = false;
}

If this is provided by your dynamic.core, I think this overload should be chosen before the std lib one.

like image 41
Justin W Avatar answered Nov 09 '22 05:11

Justin W