February 07, 2007
Hasan Aljudy wrote:
> Walter Bright wrote:
>>  From my point of view, evil uses of it are things like version control:
>>
>>     mixin(import("versions.txt"));
>>
>> where versions.txt contains:
>>
>>     version = FOO;
>>     version = BAR;
>>
>> etc., or other uses that subvert the right way to do things. One should think long and hard about using textual import to import D code.
> 
> Why is that evil? I think it's actually a great idea. "versions" are a sort of configuration that determines which code should be compiled and which code shouldn't. Storing this configuration in a separate file makes sense to me.

The right way to do versions that cut across multiple files is to abstract the versioning into an API, and implement the different versions in different modules.

This is a lot easier to manage when you're dealing with larger, more complex code, although it is more work up front.
February 07, 2007
Serg Kovrov wrote:
> Ary Manzana wrote:
>> But... I'm wondering which are the evil uses of it. For me it's now almost impossible not to program with an IDE (big projects, I mean). At least in Java. Maybe compile time stuff will make it such that an IDE won't be needed anymore. But it's very hard for me to see that happening.
> 
> I believe by 'evil use', Walter meant evil use of mixins, not IDE's. Isn't he?
> 

Yes. IDEs aren't evil.
February 07, 2007
"Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message news:eqbu2l$1s7t$1@digitaldaemon.com...
>
>
> Vladimir Panteleev wrote:
>> On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound@digitalmars.com> wrote:
>>
>>> http://www.digitalmars.com/d/changelog.html
>>
>> Hmm. What would prevent someone from writing programs like:
>>    writef(import("/etc/passwd"));
>> and trick someone to compile this program for them (under the pretext
>> that they don't have a D compiler, for example) to steal the user list
>> (or the contents of any other file with a known absolute or relative path
>> on the victim's system)?
>>
>> IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
>>
>
> Well, theoretically nothing prevents someone from writing a virus in C++ and trick someone to compile and run it.

But you don't need them to run Vladimir's example, just compile it.  They send you back the compiled program ("Thanks for compiling it for me!") and you run it.  The passwords are imbedded in the binary.  C++ can't do this quite as easily.


February 07, 2007
Andreas Kochenburger wrote:
> BLS wrote:
>> I guess here is a need for further explaination.
>>
>> Either I am an complete idiot (not completely unrealistic) and missunderstood something, or a new, quit radical, programming paradigmn change is on it s way.  I mean it is difficult to realize the implications.
>> Bjoern
> 
> I am not a D programmer (yet) only observing what is happening.
> 
> I compare the new "code generation at compile-time" stuff in D with Forth. Forth also has a built-in interpreter & compiler which extends the language and can also execute macros at compile-time through EVALUATE. Of course Forth is much more low-level than D. But IMO the new mixins are not a "radical programming paradigm change".
> 
> Perhaps I just did misunderstand something?
> 
> Andreas

I'm not familiar with forth.  Can you provide some examples?  Does it allow partial macro definitions.  Can you apply string operations on them at compile time?

-Joel
February 07, 2007
Vladimir Panteleev wrote:
> On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound@digitalmars.com> wrote:
> 
>> http://www.digitalmars.com/d/changelog.html
> 
> Hmm. What would prevent someone from writing programs like:
>    writef(import("/etc/passwd"));
> and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)?
> 
> IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.

How would the bad person see the output of the compilation?

Andrei
February 07, 2007
On Wed, 07 Feb 2007 09:51:17 +0200, Andrei Alexandrescu (See Website For Email) <SeeWebsiteForEmail@erdani.org> wrote:

> Vladimir Panteleev wrote:
>> On Tue, 06 Feb 2007 06:54:18 +0200, Walter Bright <newshound@digitalmars.com> wrote:
>>
>>> http://www.digitalmars.com/d/changelog.html
>>
>> Hmm. What would prevent someone from writing programs like:
>>    writef(import("/etc/passwd"));
>> and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)?
>>
>> IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.
>
> How would the bad person see the output of the compilation?

In this particular example, the idea is to trick someone to compile a program for you and send you back the binary, under a pretext similar to "I don't have a D compiler" or "I can't/don't want to install the D compiler on my system". The fact that a compiler can embed random files in the resulting binary from his filesystem isn't obvious to a person familiar with compilers in general and not expecting similar behavior from a tool which is supposed to work with just a given set of source files.

-- 
Best regards,
  Vladimir                          mailto:thecybershadow@gmail.com
February 07, 2007
On Wed, 07 Feb 2007 06:20:51 +0300, Walter Bright <newshound@digitalmars.com> wrote:

> What it's for is to:
>
> 1) import data for a string constant
> 2) import code that's in DSL (Domain Specific Language), not D, form.

Can you provide some examples of DSL the new D feature is intended for?

For example, what if I want to implement something like to RubyOnRails ActiveRecord DSL (http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html)? This is an ordinal Ruby code:

  class Account < ActiveRecord::Base
    validates_presence_of     :subdomain, :name, :email_address, :password
    validates_uniqueness_of   :subdomain
    validates_acceptance_of   :terms_of_service, :on => :create
    validates_confirmation_of :password, :email_address, :on => :create
  end

I may wish to translate it in the following D fragment (with an exception that in D I must explicitly describe all table fields):

 mixin( DActiveRecord!(
 `class Account
    field subdomain varchar(20)
    field name varchar(100)
    field email_address varchar(255)
    field password varchar(32)
    field term_of_service int
    validates_presence_of subdomain, name, email_address, password
    validates_uniqueness_of subdomain
    validates_acceptance_of terms_of_service, on => create
    validates_confirmation_of password, email_address, on => create
  end` ) );

The template DActiveRecord must parse DSL string at compile time and produce another string with Account class implementation in D. With all necessary symantic analysis and constraints (for example, it is impossible to use name of field in 'validate_presence_of' if it isn't described as 'field').

Do you think this task can be done with D templates at complile time?

-- 
Regards,
Yauheni Akhotnikau
February 07, 2007
On Wed, 07 Feb 2007 08:30:31 +0200
"Vladimir Panteleev" <thecybershadow@gmail.com> wrote:

> Hmm. What would prevent someone from writing programs like:
>    writef(import("/etc/passwd"));
> and trick someone to compile this program for them (under the pretext that they don't have a D compiler, for example) to steal the user list (or the contents of any other file with a known absolute or relative path on the victim's system)?
> 
> IMO, the compiler should at least issue a warning when importing a file not located in/under the source file's directory. Although, if the source emits a lot of pragma(msg) messages, the warning might get cluttered by those - or this might be concealed in a large program with a lot of files. A better security-wise solution is to disallow importing files outside the source file's directory, unless specified by the user on the command-line.

I whould even go one step further and limit import() to just import files in the -I path. That whould have a few implications:

- Except you have weird import paths, import() can not lead to include any
  given "evil" file, it should then be as secure or insecure as C's #include
- One whould not be able to include any given file on the fs, but I think
  that shouldnt be a problem, since most of the time the dsl files should lie
  somewhere around in the source-tree.
- You whould use import() much like import, which at least sounds more consistent.
  For example:
  import("foo.d"); whould include the same file as
  import foo; whould import.
  Note that the semantic is still different and that import needs the file extension (as
  it might often be used to include non-d files) where import does not.
  Alternative: Allow import() just to include files with a predifined extension, then
  one could use the package.subpackage.module syntax as well.

Questions that arise to me while writing this:
* since import() does not the same thing as import ...; shouldnt it be renamed to something else?
  (say include)

* if one whould restrict import() to import-paths whould it be senseful to allow subdirectories
  to be specified?
  (say import("files_written_in_my_dsl/foo.dsl"))
  Note here that this whould still not allow directories "above" the import paths.

Henning
February 07, 2007
Yauheni Akhotnikau wrote:
> On Wed, 07 Feb 2007 06:20:51 +0300, Walter Bright <newshound@digitalmars.com> wrote:
> 
>> What it's for is to:
>>
>> 1) import data for a string constant
>> 2) import code that's in DSL (Domain Specific Language), not D, form.
> 
> Can you provide some examples of DSL the new D feature is intended for?
> 
> For example, what if I want to implement something like to RubyOnRails ActiveRecord DSL (http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html)? This is an ordinal Ruby code:
> 
>   class Account < ActiveRecord::Base
>     validates_presence_of     :subdomain, :name, :email_address, :password
>     validates_uniqueness_of   :subdomain
>     validates_acceptance_of   :terms_of_service, :on => :create
>     validates_confirmation_of :password, :email_address, :on => :create
>   end
> 
> I may wish to translate it in the following D fragment (with an exception that in D I must explicitly describe all table fields):
> 
>  mixin( DActiveRecord!(
>  `class Account
>     field subdomain varchar(20)
>     field name varchar(100)
>     field email_address varchar(255)
>     field password varchar(32)
>     field term_of_service int
>     validates_presence_of subdomain, name, email_address, password
>     validates_uniqueness_of subdomain
>     validates_acceptance_of terms_of_service, on => create
>     validates_confirmation_of password, email_address, on => create
>   end` ) );
> 
> The template DActiveRecord must parse DSL string at compile time and produce another string with Account class implementation in D. With all necessary symantic analysis and constraints (for example, it is impossible to use name of field in 'validate_presence_of' if it isn't described as 'field').
> 
> Do you think this task can be done with D templates at complile time?
> 
> --Regards,
> Yauheni Akhotnikau

Almost certainly.
February 07, 2007
Chris Nicholson-Sauls wrote:

>> "writef".length == "printf".length
> 
> But the "printf" version is -= "import std.stdio;".length + 1;

If you use printf, you should use "import std.c.stdio;"

That it works without it is a long-standing bug, IMHO.

> That said, for examplar|demonstrative D code I'd just assume
> avoid printf regardless. It just isn't "the D way."

I don't think there is anything inherently wrong with
using printf or the rest of the C standard library,
as long as it is explicitly imported by the D code ?
Having "printf" defined in Object is evil, though...

--anders