www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Scripting again.

reply so <so so.do> writes:
Hello!

In D, it is much harder to say something is impossible to implement  
comparing to other languages.
If you are coming from C/C++ land, you should know that if you want to  
script your program,
you are going to fall back to another language, possibly a "scripting"  
language.
But why? why should i fall back to a dummy language for this? Tons of  
workarounds to export stuff, it is just a mess!
It doesn't matter if we have tools like boost python bindings or PyD, it  
is still ugly.

All i can see right now is the lack of compile(file, module dependencies,  
...).
Is it just technical limitations or is this is another religious issue?

Thanks!

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
so <so so.do> wrote:

 Hello!

 In D, it is much harder to say something is impossible to implement  
 comparing to other languages.
 If you are coming from C/C++ land, you should know that if you want to  
 script your program,
 you are going to fall back to another language, possibly a "scripting"  
 language.
 But why? why should i fall back to a dummy language for this? Tons of  
 workarounds to export stuff, it is just a mess!
 It doesn't matter if we have tools like boost python bindings or PyD, it  
 is still ugly.

 All i can see right now is the lack of compile(file, module  
 dependencies, ...).
 Is it just technical limitations or is this is another religious issue?

Mostly, there is no D compiler written in D that can be included in the standard library. -- Simen
Dec 09 2010
next sibling parent so <so so.do> writes:
This is the only reason i can think of too.
The trouble with this as far as i can see is that when you have this  
feature (compile),
you actually dictate that a D implementation must be free(?).
Thinking about this, this is not something wrong. A compiler is not an  
ordinary program.
As an OS provider, if you implement a language you are doing it for your  
own sake, and the profit is quite big.

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/9/10 12:25 PM, Simen kjaeraas wrote:
 so <so so.do> wrote:

 Hello!

 In D, it is much harder to say something is impossible to implement
 comparing to other languages.
 If you are coming from C/C++ land, you should know that if you want to
 script your program,
 you are going to fall back to another language, possibly a "scripting"
 language.
 But why? why should i fall back to a dummy language for this? Tons of
 workarounds to export stuff, it is just a mess!
 It doesn't matter if we have tools like boost python bindings or PyD,
 it is still ugly.

 All i can see right now is the lack of compile(file, module
 dependencies, ...).
 Is it just technical limitations or is this is another religious issue?

Mostly, there is no D compiler written in D that can be included in the standard library.

A system() call should work as well. A larger problem is dynamically executing functions that have just been compiled. Andrei
Dec 09 2010
prev sibling parent so <so so.do> writes:
 A system() call should work as well. A larger problem is dynamically  
 executing functions that have just been compiled.

For that to work, host needs a language environment installed. Or maybe you mean distributing compiler with the project? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
so Wrote:

 Hello!

 All i can see right now is the lack of compile(file, module dependencies,  
 ...).
 Is it just technical limitations or is this is another religious issue?
 
 Thanks!

You add a scripting language to your program for two reasons. You want to make your program expendable after release or you want to change behavior during run time. These goals can be achieved with dynamic linking. This would require having a compiler to the language (some language have libraries for this) and possibly other issues. I'm of the opinion that languages like Lua/MiniD are great ways to achieve these goals as they are small efficient languages and were made specifically for embedding. I'm considering the idea of using Lua scripts as configuration files, but haven't yet put into practice to judge if it is beneficial. I do not believe it is common to add scripting to avoid the language you are writing code in.
Dec 09 2010
next sibling parent reply so <so so.do> writes:
 I'm of the opinion that languages like Lua/MiniD are great ways to  
 achieve these goals as they are small efficient languages and were made  
 specifically for embedding. I'm considering the idea of using Lua  
 scripts as configuration files, but haven't yet put into practice to  
 judge if it is beneficial.

I agree there are some handy tools, but they exist because of the shortcomings of said languages, not because it is the way it should be. // define here class A { ... } // and export somewhere export(A); export(A.method); ... export(that); export(whatever); ... You see how stupid is this? How ugly it can get? For actually zero gain?
 I do not believe it is common to add scripting to avoid the language you  
 are writing code in.

Absolutely! -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
so Wrote:

 // define here
 class A {
 ...
 }
 
 // and export somewhere
 export(A);
 export(A.method);
 ...
 export(that);
 export(whatever);
 ...
 
 You see how stupid is this? How ugly it can get? For actually zero gain?

How is this different from using dynamic libraries? Surely you don't think plug-ins are a zero gain?
Dec 09 2010
parent Jesse Phillips <jessekphillips+D gmail.com> writes:
so Wrote:

 How is this different from using dynamic libraries?

there is nothing annoying there. --- export function() { ... } ---

Ok, but then you also have external function(); In the DLL, I think... And if you are importing a function from a DLL there is still some wrapper code that goes with it. And from your previous example you would still need the source for the class available so that you could build the DLL.
 But falling back to a dummy language for this is zero gain. You don't fall  
 back to another language to use a dynamic library.
 For scripting, you use another language mostly because you have to.

I guess I can't disagree with your main point. I couldn't think of a reason you would use python then do scripting in Lua. Of course people do some weird things: http://www.equi4.com/wikis/lua/25
Dec 09 2010
prev sibling parent so <so so.do> writes:
 How is this different from using dynamic libraries?

there is nothing annoying there. --- export function() { ... } --- That is it! All you need is here.
 Surely you don't think plug-ins are a zero gain?

program is grand. But falling back to a dummy language for this is zero gain. You don't fall back to another language to use a dynamic library. For scripting, you use another language mostly because you have to. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
prev sibling parent reply %u <e ee.com> writes:
== Quote from so (so so.do)'s article
 Hello!
 In D, it is much harder to say something is impossible to implement
 comparing to other languages.
 If you are coming from C/C++ land, you should know that if you want to
 script your program,
 you are going to fall back to another language, possibly a "scripting"
 language.
 But why? why should i fall back to a dummy language for this? Tons of
 workarounds to export stuff, it is just a mess!
 It doesn't matter if we have tools like boost python bindings or PyD, it
 is still ugly.
 All i can see right now is the lack of compile(file, module dependencies,
 ...).
 Is it just technical limitations or is this is another religious issue?
 Thanks!

Doesn't this work?? import std.file; import std.script; Script s = new Script(cast(ubyte[]) read("script1.d")); s.compile(); s.execute();
Dec 09 2010
next sibling parent reply so <so so.do> writes:
 Doesn't this work??

 import std.file;
 import std.script;

 Script s = new Script(cast(ubyte[]) read("script1.d"));
 s.compile();
 s.execute();

What is this supposed to mean? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
parent reply %u <e ee.com> writes:
== Quote from so (so so.do)'s article
 Doesn't this work??

 import std.file;
 import std.script;

 Script s = new Script(cast(ubyte[]) read("script1.d"));
 s.compile();
 s.execute();


This should be a bit more clear (untested code). --scrip1.d import std.stdio; writefln(i); ---- --main.d import std.file; import std.script; void main(){ Script s = new Script(cast(ubyte[]) read("script1.d")); assert(!s.validate); int i = 1; assert(s.validate); s.compile(); s.execute(); // output 1 } ----
Dec 09 2010
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
%u schrieb:
 == Quote from so (so so.do)'s article
 Doesn't this work??

 import std.file;
 import std.script;

 Script s = new Script(cast(ubyte[]) read("script1.d"));
 s.compile();
 s.execute();


This should be a bit more clear (untested code). --scrip1.d import std.stdio; writefln(i); ---- --main.d import std.file; import std.script; void main(){ Script s = new Script(cast(ubyte[]) read("script1.d")); assert(!s.validate); int i = 1; assert(s.validate); s.compile(); s.execute(); // output 1 } ----

That wouldn't be just a script but a runtime-string-mixin (or something like that). I don't think something like that is feasible in a compiled language.
Dec 09 2010
parent reply %u <e ee.com> writes:
== Quote from Daniel Gibson (metalcaedes gmail.com)'s article
 %u schrieb:
 == Quote from so (so so.do)'s article
 Doesn't this work??

 import std.file;
 import std.script;

 Script s = new Script(cast(ubyte[]) read("script1.d"));
 s.compile();
 s.execute();


This should be a bit more clear (untested code). --scrip1.d import std.stdio; writefln(i); ---- --main.d import std.file; import std.script; void main(){ Script s = new Script(cast(ubyte[]) read("script1.d")); assert(!s.validate); int i = 1; assert(s.validate); s.compile(); s.execute(); // output 1 } ----


 I don't think something like that is feasible in a compiled language.

s.execute(i); Where in the script i will be the first arg in main? That way the compiler knows which variables to export.
Dec 09 2010
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
%u schrieb:
 == Quote from Daniel Gibson (metalcaedes gmail.com)'s article
 %u schrieb:
 == Quote from so (so so.do)'s article
 Doesn't this work??

 import std.file;
 import std.script;

 Script s = new Script(cast(ubyte[]) read("script1.d"));
 s.compile();
 s.execute();


--scrip1.d import std.stdio; writefln(i); ---- --main.d import std.file; import std.script; void main(){ Script s = new Script(cast(ubyte[]) read("script1.d")); assert(!s.validate); int i = 1; assert(s.validate); s.compile(); s.execute(); // output 1 } ----


 I don't think something like that is feasible in a compiled language.

s.execute(i); Where in the script i will be the first arg in main? That way the compiler knows which variables to export.

I guess something like that is possible. I'd prefer something like s.call("main", i); and also s.call("foo", 42, x); though - so you can define multiple functions in a script and call them. Or maybe, with more magic and support within the D compiler s.main(i); s.foo(42,x); But that means that the compiler needs to know the Script type, create a class for each script that contains the functions called on the script ("main", "foo"), create stubs for them that either do something like call("foo",i) or, if no function foo with an appropriate argument is found in the script, throws an exception.. Probably possible, but certainly not easy. The first suggestion however (s.call("foo", i)) should be possible without support in the D compiler, all the work would be done in the Script class. Still not trivial, of course, especially with arguments for called functions and their type etc.
Dec 09 2010
next sibling parent %u <e ee.com> writes:
== Quote from Daniel Gibson (metalcaedes gmail.com)'s article
 I guess something like that is possible.
 I'd prefer something like
 s.call("main", i);
 and also
 s.call("foo", 42, x);
 though - so you can define multiple functions in a script and call them.

Of course, I was thinking that if you omit the function name it would default to main, but that would prohibit the use of a string as first argument :)
 Or maybe, with more magic and support within the D compiler
 s.main(i);
 s.foo(42,x);
 But that means that the compiler needs to know the Script type, create a class
 for each script that contains the functions called on the script ("main",
 "foo"), create stubs for them that either do something like call("foo",i) or,
if
   no function foo with an appropriate argument is found in the script, throws
an
 exception..
 Probably possible, but certainly not easy.
 The first suggestion however (s.call("foo", i)) should be possible without
 support in the D compiler, all the work would be done in the Script class.
Still
 not trivial, of course, especially with arguments for called functions and
their
 type etc.

I would be more than happy with only the first method :) Would DMDscript help?
Dec 09 2010
prev sibling next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
Daniel Gibson wrote:
 Or maybe, with more magic and support within the D compiler
 s.main(i);
 s.foo(42,x);

We can do that today - write an opDispatch that forwards to an associative array. It's actually pretty trivial.
Dec 09 2010
parent Daniel Gibson <metalcaedes gmail.com> writes:
Adam Ruppe schrieb:
 Daniel Gibson wrote:
 Or maybe, with more magic and support within the D compiler
 s.main(i);
 s.foo(42,x);

We can do that today - write an opDispatch that forwards to an associative array. It's actually pretty trivial.

Cool. I should get familiar with D2 one day ;-)
Dec 09 2010
prev sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
so schrieb:
 I guess something like that is possible.

 I'd prefer something like
 s.call("main", i);
 and also
 s.call("foo", 42, x);
 though - so you can define multiple functions in a script and call them.

 Or maybe, with more magic and support within the D compiler
 s.main(i);
 s.foo(42,x);
 But that means that the compiler needs to know the Script type, create 
 a class for each script that contains the functions called on the 
 script ("main", "foo"), create stubs for them that either do something 
 like call("foo",i) or, if   no function foo with an appropriate 
 argument is found in the script, throws an exception..
 Probably possible, but certainly not easy.
 The first suggestion however (s.call("foo", i)) should be possible 
 without support in the D compiler, all the work would be done in the 
 Script class. Still not trivial, of course, especially with arguments 
 for called functions and their type etc.

The actual use case in my scenario is manipulating your program. not necessarily the other way around. class ScriptBinary { void run() {..} } // [modules] is the list of modules you give access to script // if [modules] contains "std", script can access "std" and it is child modules. ScriptBinary compile(string filename, string[] modules, ...) { ... }

I think for a proper general purpose scripting solution (like one would expect in std.script) both ways are needed. But you're right, of course you need a way to tell the script what modules (and maybe also functions/delegates so it can call local functions in your code, but not all of them) it may access and how.
Dec 09 2010
prev sibling parent %u <e ee.com> writes:
== Quote from so (so so.do)'s article
 This should be a bit more clear (untested code).

 --scrip1.d
 import std.stdio;
 writefln(i);
 ----

 --main.d
 import std.file;
 import std.script;

 void main(){
   Script s = new Script(cast(ubyte[]) read("script1.d"));
   assert(!s.validate);
   int i = 1;
   assert(s.validate);
   s.compile();
   s.execute(); // output 1
 }
 ----

Sorry i thought you were implying something, knowing the the topic is touchy for some people that has no idea how serious is this tiny issue.

I was kind of implying the script module existed, but I'm not really touchy about that ;P
Dec 09 2010
prev sibling next sibling parent so <so so.do> writes:
 This should be a bit more clear (untested code).

 --scrip1.d
 import std.stdio;
 writefln(i);
 ----

 --main.d
 import std.file;
 import std.script;

 void main(){
   Script s = new Script(cast(ubyte[]) read("script1.d"));
   assert(!s.validate);
   int i = 1;
   assert(s.validate);
   s.compile();
   s.execute(); // output 1
 }
 ----

Oh, D doesn't have a scripting module as far as i know. Sorry i thought you were implying something, knowing the the topic is touchy for some people that has no idea how serious is this tiny issue. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
prev sibling next sibling parent so <so so.do> writes:
 I guess something like that is possible.

 I'd prefer something like
 s.call("main", i);
 and also
 s.call("foo", 42, x);
 though - so you can define multiple functions in a script and call them.

 Or maybe, with more magic and support within the D compiler
 s.main(i);
 s.foo(42,x);
 But that means that the compiler needs to know the Script type, create a  
 class for each script that contains the functions called on the script  
 ("main", "foo"), create stubs for them that either do something like  
 call("foo",i) or, if   no function foo with an appropriate argument is  
 found in the script, throws an exception..
 Probably possible, but certainly not easy.
 The first suggestion however (s.call("foo", i)) should be possible  
 without support in the D compiler, all the work would be done in the  
 Script class. Still not trivial, of course, especially with arguments  
 for called functions and their type etc.

The actual use case in my scenario is manipulating your program. not necessarily the other way around. class ScriptBinary { void run() {..} } // [modules] is the list of modules you give access to script // if [modules] contains "std", script can access "std" and it is child modules. ScriptBinary compile(string filename, string[] modules, ...) { ... } -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010
prev sibling parent so <so so.do> writes:
 I think for a proper general purpose scripting solution (like one would  
 expect in std.script) both ways are needed.

Oh you are right, supporting one side is a dead end. class ScriptBinary { void run() {..} void call(...) {...} void opDispatch(...) {... call(); } // As Adam also pointed out. } -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 09 2010