June 20, 2011
On 2011-06-20 14:35, Dmitry Olshansky wrote:
> On 20.06.2011 15:35, Jacob Carlborg wrote:
>> On 2011-06-20 10:59, Dmitry Olshansky wrote:
>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>
>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>> there
>>>>> is Target struct or class):
>>>>> //somewhere at top
>>>>> Target cool_lib, ...;
>>>>>
>>>>> then:
>>>>> with(cool_lib) {
>>>>> flags = "-L-lz";
>>>>> }
>>>>>
>>>>> I'd even expect special types like Executable, Library and so on.
>>>>
>>>> The user shouldn't have to create the necessary object. If it does,
>>>> how would the tool get it then?
>>>>
>>> If we settle on effectively evaluating orbspec like this:
>>> //first module
>>> module orb_orange;
>>> mixin(import ("orange.orbspec"));
>>> //
>>>
>>> // builder entry point
>>> void main()
>>> {
>>> foreach(member; __traits(allMembers, orb_orange))
>>> {
>>> static if(typeof(member) == Target){
>>> //do necessary actions, sort out priority and construct a worklist
>>> }
>>> else //static if (...) //...could be others I mentioned
>>> {
>>> }
>>> }
>>> //all the work goes there
>>> }
>>>
>>> Should be straightforward? Alternatively with local imports we can pack
>>> it in a struct instead of separate module, though errors in script would
>>> be harder to report (but at least static constructors would be
>>> controlled!). More adequatly would be, of course, to pump it to dmd from
>>> stdin...
>>
>> I had no idea that you could do that. It seems somewhat complicated
>> and like a hack. Also note that Orbit is currently written in D1,
>> which doesn't have __traits.
>>
>
> Well, everything about compile-time introspection could be labeled like
> a hack. In fact I just seen the aforementioned "hack" on a much grander
> scale being used in upcoming std module, see std.benchmarking:
> https://github.com/D-Programming-Language/phobos/pull/85/files#L1R577
> And personally hacks should look ugly or they are just features or at
> best shortcuts ;)

I personally think that just because Phobos uses these features will not make them less "hackish".

> Personal things aside I still suggest you to switch it to D2. I can
> understand if Phobos is just not up to snuff for you yet (btw cute curl
> wrapper is coming in a matter of days). But other then that... just look
> at all these candies ( opDispatch anyone? ) :)
> And even if porting is a piece of work, I suspect there a lot of people
> out there that would love to help this project.
> (given the lofty goal that config would be written in D, and not Ruby)

D2 has many new cool feature and I would love to use some of them, but every time I try they don't work. I'm tried of using a language that's not ready. I still think Tango is a better library and I like it better than Phobos. Although Phobos is doing a great job of filling in the feature gaps in every new release.

-- 
/Jacob Carlborg
June 20, 2011
On 20.06.2011 23:39, Nick Sabalausky wrote:
> "Dmitry Olshansky"<dmitry.olsh@gmail.com>  wrote in message
> news:itn2el$2t2v$1@digitalmars.com...
>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>
>>>> Why having name as run-time parameter? I'd expect more like (given there
>>>> is Target struct or class):
>>>> //somewhere at top
>>>> Target cool_lib, ...;
>>>>
>>>> then:
>>>> with(cool_lib) {
>>>> flags = "-L-lz";
>>>> }
>>>>
>>>> I'd even expect special types like Executable, Library and so on.
>>> The user shouldn't have to create the necessary object. If it does, how
>>> would the tool get it then?
>>>
>> If we settle on effectively evaluating orbspec like this:
>> //first module
>> module orb_orange;
>> mixin(import ("orange.orbspec"));
>> //
>>
>> // builder entry point
>> void main()
>> {
>>      foreach(member; __traits(allMembers, orb_orange))
>>      {
>>          static if(typeof(member) == Target){
>>              //do necessary actions,  sort out priority and construct a
>> worklist
>>          }
>>          else //static if (...) //...could be others I mentioned
>>          {
>>          }
>>      }
>>      //all the work goes there
>> }
>>
>> Should be straightforward? Alternatively with local imports we can pack it
>> in a struct instead of separate module, though errors in script would be
>> harder to report (but at least static constructors would be controlled!).
>> More adequatly would be, of course, to pump it to dmd from stdin...
>>
> Target would be part of Orb. Why not just make Target's ctor register itself
> with the rest of Orb?
>
>
Nice thinking, but default constructors for structs?
 Of course, it could be a class... Then probably there could be usefull derived things like these Executable, Library,  etc.

-- 
Dmitry Olshansky

June 20, 2011
On 2011-06-20 14:49, Dmitry Olshansky wrote:
> On 20.06.2011 16:35, Dmitry Olshansky wrote:
>> On 20.06.2011 15:35, Jacob Carlborg wrote:
>>> On 2011-06-20 10:59, Dmitry Olshansky wrote:
>>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>>
>>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>>> there
>>>>>> is Target struct or class):
>>>>>> //somewhere at top
>>>>>> Target cool_lib, ...;
>>>>>>
>>>>>> then:
>>>>>> with(cool_lib) {
>>>>>> flags = "-L-lz";
>>>>>> }
>>>>>>
>>>>>> I'd even expect special types like Executable, Library and so on.
>>>>>
>>>>> The user shouldn't have to create the necessary object. If it does,
>>>>> how would the tool get it then?
>>>>>
>>>> If we settle on effectively evaluating orbspec like this:
>>>> //first module
>>>> module orb_orange;
>>>> mixin(import ("orange.orbspec"));
>>>> //
>>>>
>>>> // builder entry point
>>>> void main()
>>>> {
>>>> foreach(member; __traits(allMembers, orb_orange))
>>>> {
>>>> static if(typeof(member) == Target){
>>>> //do necessary actions, sort out priority and construct a worklist
>>>> }
>>>> else //static if (...) //...could be others I mentioned
>>>> {
>>>> }
>>>> }
>>>> //all the work goes there
>>>> }
>>>>
>>>> Should be straightforward? Alternatively with local imports we can pack
>>>> it in a struct instead of separate module, though errors in script
>>>> would
>>>> be harder to report (but at least static constructors would be
>>>> controlled!). More adequatly would be, of course, to pump it to dmd
>>>> from
>>>> stdin...
>>>
>>> I had no idea that you could do that. It seems somewhat complicated
>>> and like a hack. Also note that Orbit is currently written in D1,
>>> which doesn't have __traits.
>>>
>>
>> Well, everything about compile-time introspection could be labeled
>> like a hack. In fact I just seen the aforementioned "hack" on a much
>> grander scale being used in upcoming std module, see std.benchmarking:
>> https://github.com/D-Programming-Language/phobos/pull/85/files#L1R577
>> And personally hacks should look ugly or they are just features or at
>> best shortcuts ;)
>>
>> Personal things aside I still suggest you to switch it to D2. I can
>> understand if Phobos is just not up to snuff for you yet (btw cute
>> curl wrapper is coming in a matter of days). But other then that...
>> just look at all these candies ( opDispatch anyone? ) :)
>> And even if porting is a piece of work, I suspect there a lot of
>> people out there that would love to help this project.
>> (given the lofty goal that config would be written in D, and not Ruby)
>>
> Just looked through the source , it seems like you are doing a lot of
> work that's already been done in Phobos, so it might be worth doing a
> port to D2. Some simple wrappers might be needed, but ultimately:

First I have to say that these simple models are no reason to port to D2. Second, here are a couple of other reasons:

* These modules (at least some of them) are quite old, pieces of some of them originate back from 2007 (before D2)

* These modules also started out as common API for Phobos and Tango functions

* Some of these modules also contains specific functions and names for easing Java and C++ porting

Overall I like the API of the modules, some functions are aliases for Tango/Phobos functions with names I like better and some are just wrappers with a new API.

> util.traits --> std.traits

As far as I can see, most of these functions don't exist in std.traits.

> core.array --> std.array + std.algorithm

When I work with arrays I want to work with arrays not some other kind of type like a range. I do understand the theoretical idea about having containers and algorithm separated but in practice I've never needed it.

> io.path --> std.file & std.path

Some of these exist in std.file and some don't.

> orgb.util.OptinoParser --> std.getopt

This is a wrapper for the Tango argument parse, because I like this API better.

> util.singleton should probably be pulled into Phobos, but a thread safe
> shared version.

Yes, but it isn't in Phobos yet.

-- 
/Jacob Carlborg
June 20, 2011
On 2011-06-20 15:28, Andrei Alexandrescu wrote:
> On 6/20/11 6:35 AM, Jacob Carlborg wrote:
>> On 2011-06-20 10:59, Dmitry Olshansky wrote:
>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>
>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>> there
>>>>> is Target struct or class):
>>>>> //somewhere at top
>>>>> Target cool_lib, ...;
>>>>>
>>>>> then:
>>>>> with(cool_lib) {
>>>>> flags = "-L-lz";
>>>>> }
>>>>>
>>>>> I'd even expect special types like Executable, Library and so on.
>>>>
>>>> The user shouldn't have to create the necessary object. If it does,
>>>> how would the tool get it then?
>>>>
>>> If we settle on effectively evaluating orbspec like this:
>>> //first module
>>> module orb_orange;
>>> mixin(import ("orange.orbspec"));
>>> //
>>>
>>> // builder entry point
>>> void main()
>>> {
>>> foreach(member; __traits(allMembers, orb_orange))
>>> {
>>> static if(typeof(member) == Target){
>>> //do necessary actions, sort out priority and construct a worklist
>>> }
>>> else //static if (...) //...could be others I mentioned
>>> {
>>> }
>>> }
>>> //all the work goes there
>>> }
>>>
>>> Should be straightforward? Alternatively with local imports we can pack
>>> it in a struct instead of separate module, though errors in script would
>>> be harder to report (but at least static constructors would be
>>> controlled!). More adequatly would be, of course, to pump it to dmd from
>>> stdin...
>>
>> I had no idea that you could do that. It seems somewhat complicated and
>> like a hack. Also note that Orbit is currently written in D1, which
>> doesn't have __traits.
>
> std.benchmark (https://github.com/D-Programming-Language/phobos/pull/85)
> does that, too. Overall I believe porting Orbit to D2 and making it use
> D2 instead of Ruby in configuration would increase its chances to become
> popular and accepted in tools/.
>
> Andrei

See my reply to Dmitry. BTW has std.benchmark gone through the regular review process?

-- 
/Jacob Carlborg
June 20, 2011
On 2011-06-20 22:45, Dmitry Olshansky wrote:
> On 20.06.2011 23:39, Nick Sabalausky wrote:
>> "Dmitry Olshansky"<dmitry.olsh@gmail.com> wrote in message
>> news:itn2el$2t2v$1@digitalmars.com...
>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>
>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>> there
>>>>> is Target struct or class):
>>>>> //somewhere at top
>>>>> Target cool_lib, ...;
>>>>>
>>>>> then:
>>>>> with(cool_lib) {
>>>>> flags = "-L-lz";
>>>>> }
>>>>>
>>>>> I'd even expect special types like Executable, Library and so on.
>>>> The user shouldn't have to create the necessary object. If it does, how
>>>> would the tool get it then?
>>>>
>>> If we settle on effectively evaluating orbspec like this:
>>> //first module
>>> module orb_orange;
>>> mixin(import ("orange.orbspec"));
>>> //
>>>
>>> // builder entry point
>>> void main()
>>> {
>>> foreach(member; __traits(allMembers, orb_orange))
>>> {
>>> static if(typeof(member) == Target){
>>> //do necessary actions, sort out priority and construct a
>>> worklist
>>> }
>>> else //static if (...) //...could be others I mentioned
>>> {
>>> }
>>> }
>>> //all the work goes there
>>> }
>>>
>>> Should be straightforward? Alternatively with local imports we can
>>> pack it
>>> in a struct instead of separate module, though errors in script would be
>>> harder to report (but at least static constructors would be
>>> controlled!).
>>> More adequatly would be, of course, to pump it to dmd from stdin...
>>>
>> Target would be part of Orb. Why not just make Target's ctor register
>> itself
>> with the rest of Orb?
>>
>>
> Nice thinking, but default constructors for structs?
> Of course, it could be a class... Then probably there could be usefull
> derived things like these Executable, Library, etc.

I really don't like that the users needs to create the targets. The good thing about Ruby is that the user can just call a function and pass a block to the function. Then the tool can evaluate the block in the context of an instance. The user would never have to care about instances.

-- 
/Jacob Carlborg
June 20, 2011
On 21.06.2011 1:36, Jacob Carlborg wrote:
> On 2011-06-20 22:45, Dmitry Olshansky wrote:
>> On 20.06.2011 23:39, Nick Sabalausky wrote:
>>> "Dmitry Olshansky"<dmitry.olsh@gmail.com> wrote in message
>>> news:itn2el$2t2v$1@digitalmars.com...
>>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>>
>>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>>> there
>>>>>> is Target struct or class):
>>>>>> //somewhere at top
>>>>>> Target cool_lib, ...;
>>>>>>
>>>>>> then:
>>>>>> with(cool_lib) {
>>>>>> flags = "-L-lz";
>>>>>> }
>>>>>>
>>>>>> I'd even expect special types like Executable, Library and so on.
>>>>> The user shouldn't have to create the necessary object. If it does, how
>>>>> would the tool get it then?
>>>>>
>>>> If we settle on effectively evaluating orbspec like this:
>>>> //first module
>>>> module orb_orange;
>>>> mixin(import ("orange.orbspec"));
>>>> //
>>>>
>>>> // builder entry point
>>>> void main()
>>>> {
>>>> foreach(member; __traits(allMembers, orb_orange))
>>>> {
>>>> static if(typeof(member) == Target){
>>>> //do necessary actions, sort out priority and construct a
>>>> worklist
>>>> }
>>>> else //static if (...) //...could be others I mentioned
>>>> {
>>>> }
>>>> }
>>>> //all the work goes there
>>>> }
>>>>
>>>> Should be straightforward? Alternatively with local imports we can
>>>> pack it
>>>> in a struct instead of separate module, though errors in script would be
>>>> harder to report (but at least static constructors would be
>>>> controlled!).
>>>> More adequatly would be, of course, to pump it to dmd from stdin...
>>>>
>>> Target would be part of Orb. Why not just make Target's ctor register
>>> itself
>>> with the rest of Orb?
>>>
>>>
>> Nice thinking, but default constructors for structs?
>> Of course, it could be a class... Then probably there could be usefull
>> derived things like these Executable, Library, etc.
>
> I really don't like that the users needs to create the targets. The good thing about Ruby is that the user can just call a function and pass a block to the function. Then the tool can evaluate the block in the context of an instance. The user would never have to care about instances.
>
I'm not getting what's wrong with  it.  Your magical block is still getting some _name_ as string right? I suspect it's even an advantage if you can't type pass arbitrary strings to a block  only proper instances, e.g. it's harder to mistype a name due to a type checking.

What's so good about having to type all these name over and over again without keeping track of how many you inadvertently referenced?

Taking your example, what if I typed name2 instead of name here, what would be the tool actions:
target "name" do |t|
    t.flags = "-L-lz"
end

Create new target and set it's flags? I can't see a reasonable error checking to disambiguate it at all.
More then that now I'm not sure what it was supposed to do in the first place - update flags of existing Target instance with name "name" ? Right now I think it could be much better to initialize them in the first place.

IMHO every time I create a build script I usually care about number of targets and their names.

P.S. Also about D as config language : take into account version statements, here they make a lot of sense.

-- 
Dmitry Olshansky

June 20, 2011
On 6/20/11 4:28 PM, Jacob Carlborg wrote:
> See my reply to Dmitry.

I see this as a dogfood issue. If there are things that should be in
Phobos and aren't, it would gain everybody to add them to Phobos.

Anyhow, it all depends on what you want to do with the tool. If it's
written in D1, we won't be able to put it on the github
D-programming-language/tools (which doesn't mean it won't become
widespread).

> BTW has std.benchmark gone through the regular review process?

I was sure someone will ask that at some point :o). The planned change
was to add a couple of functions, but then it got separated into its own
module. If several people think it's worth putting std.benchmark through
the review queue, let's do so. I'm sure the quality of the module will
be gained.


Andrei
June 21, 2011
On Mon, 20 Jun 2011 17:32:32 -0500, Andrei Alexandrescu wrote:
> On 6/20/11 4:28 PM, Jacob Carlborg wrote:
>> BTW has std.benchmark gone through the regular review process?
> 
> I was sure someone will ask that at some point :o). The planned change was to add a couple of functions, but then it got separated into its own module. If several people think it's worth putting std.benchmark through the review queue, let's do so. I'm sure the quality of the module will be gained.

I think we should.  Also, now that TempAlloc isn't up for review anymore, and both std.log and std.path have to be postponed a few weeks, the queue is open. :)

-Lars
June 21, 2011
On 2011-06-21 00:30, Dmitry Olshansky wrote:
> On 21.06.2011 1:36, Jacob Carlborg wrote:
>> On 2011-06-20 22:45, Dmitry Olshansky wrote:
>>> On 20.06.2011 23:39, Nick Sabalausky wrote:
>>>> "Dmitry Olshansky"<dmitry.olsh@gmail.com> wrote in message
>>>> news:itn2el$2t2v$1@digitalmars.com...
>>>>> On 20.06.2011 12:25, Jacob Carlborg wrote:
>>>>>> On 2011-06-19 22:28, Dmitry Olshansky wrote:
>>>>>>
>>>>>>> Why having name as run-time parameter? I'd expect more like (given
>>>>>>> there
>>>>>>> is Target struct or class):
>>>>>>> //somewhere at top
>>>>>>> Target cool_lib, ...;
>>>>>>>
>>>>>>> then:
>>>>>>> with(cool_lib) {
>>>>>>> flags = "-L-lz";
>>>>>>> }
>>>>>>>
>>>>>>> I'd even expect special types like Executable, Library and so on.
>>>>>> The user shouldn't have to create the necessary object. If it
>>>>>> does, how
>>>>>> would the tool get it then?
>>>>>>
>>>>> If we settle on effectively evaluating orbspec like this:
>>>>> //first module
>>>>> module orb_orange;
>>>>> mixin(import ("orange.orbspec"));
>>>>> //
>>>>>
>>>>> // builder entry point
>>>>> void main()
>>>>> {
>>>>> foreach(member; __traits(allMembers, orb_orange))
>>>>> {
>>>>> static if(typeof(member) == Target){
>>>>> //do necessary actions, sort out priority and construct a
>>>>> worklist
>>>>> }
>>>>> else //static if (...) //...could be others I mentioned
>>>>> {
>>>>> }
>>>>> }
>>>>> //all the work goes there
>>>>> }
>>>>>
>>>>> Should be straightforward? Alternatively with local imports we can
>>>>> pack it
>>>>> in a struct instead of separate module, though errors in script
>>>>> would be
>>>>> harder to report (but at least static constructors would be
>>>>> controlled!).
>>>>> More adequatly would be, of course, to pump it to dmd from stdin...
>>>>>
>>>> Target would be part of Orb. Why not just make Target's ctor register
>>>> itself
>>>> with the rest of Orb?
>>>>
>>>>
>>> Nice thinking, but default constructors for structs?
>>> Of course, it could be a class... Then probably there could be usefull
>>> derived things like these Executable, Library, etc.
>>
>> I really don't like that the users needs to create the targets. The
>> good thing about Ruby is that the user can just call a function and
>> pass a block to the function. Then the tool can evaluate the block in
>> the context of an instance. The user would never have to care about
>> instances.
>>
> I'm not getting what's wrong with it. Your magical block is still
> getting some _name_ as string right? I suspect it's even an advantage if
> you can't type pass arbitrary strings to a block only proper instances,
> e.g. it's harder to mistype a name due to a type checking.

This is starting to get confusing. You're supposed to be passing an arbitrary strings to the function and then _receive_ an instance to the block.

> What's so good about having to type all these name over and over again
> without keeping track of how many you inadvertently referenced?

You shouldn't have to repeat the name.

> Taking your example, what if I typed name2 instead of name here, what
> would be the tool actions:
> target "name" do |t|
> t.flags = "-L-lz"
> end

"target" works like this:

1. You call "target" passing in the name of the target and a block

2. "target" then call the block passing in an instance of a Target class (or similar)

3. In the block you then specify all the necessary settings you need for this particular target.

You should only call "target" once for each target. So, if you pass in "name2" instead of "name" you would create a new target. I haven't figured out what should happen if you call "target" twice with the same name.

Also note that this would be sufficient:

target "name" do
    flags "-l-lz"
end

In that case you wouldn't even have to care about "t" or that it even exists an instance behind the since. It would just be syntax.

You can have a look at how Rake and Rubgems do this:

If you look at the Rake examples: http://en.wikipedia.org/wiki/Rake_%28software%29 then a target would work the same as a Rake task.

Have a look at the top example of: http://rubygems.rubyforge.org/rubygems-update/Gem/Specification.html

> Create new target and set it's flags? I can't see a reasonable error
> checking to disambiguate it at all.
> More then that now I'm not sure what it was supposed to do in the first
> place - update flags of existing Target instance with name "name" ?
> Right now I think it could be much better to initialize them in the
> first place.
>
> IMHO every time I create a build script I usually care about number of
> targets and their names.
>
> P.S. Also about D as config language : take into account version
> statements, here they make a lot of sense.

Yes, version statements will be available as well.

-- 
/Jacob Carlborg
June 21, 2011
On 2011-06-21 00:32, Andrei Alexandrescu wrote:
> On 6/20/11 4:28 PM, Jacob Carlborg wrote:
>> See my reply to Dmitry.
>
> I see this as a dogfood issue. If there are things that should be in
> Phobos and aren't, it would gain everybody to add them to Phobos.

All of these are not missing. For some of the things I just like doing it differently then how Phobos does it.

> Anyhow, it all depends on what you want to do with the tool. If it's
> written in D1, we won't be able to put it on the github
> D-programming-language/tools (which doesn't mean it won't become
> widespread).

So now suddenly D1 is banned? Seems like you are trying to destroy all traces of D1. I think it would be better for all if you instead encourage people to use D of any version and not use D2.

>> BTW has std.benchmark gone through the regular review process?
>
> I was sure someone will ask that at some point :o). The planned change
> was to add a couple of functions, but then it got separated into its own
> module. If several people think it's worth putting std.benchmark through
> the review queue, let's do so. I'm sure the quality of the module will
> be gained.
>
>
> Andrei

Why would std.benchmark be an exception? Shouldn't all new modules and big refactoring of existing ones go through the review process? If none one thinks it's worth putting std.benchmark through the review process then it seems to me that people isn't thinking it worth adding to Phobos.

-- 
/Jacob Carlborg