www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Pseudo namespaces

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
I vaguely remembered I saw something like this a while ago:

http://dpaste.dzfl.pl/f11894a098c6

The trick could be more fluent, but it might have merit. Has anyone 
explored it? Is it a viable candidate for becoming a D idiom?

I was looking at this in conjunction with choosing a naming convention 
for container functions. Some functions are "stable" so that would be 
part of their name, e.g. insertStable or stableInsert. With this, it's 
possible to write lst.stable.insert.


Andrei
Dec 03 2015
next sibling parent reply Dicebot <public dicebot.lv> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
This isn't any different from namespace struct idiom, is it? I don't like it because it forces the namespace usage even if it isn't needed. There is something wrong with the module system if one needs to resort to idioms like this. My old finding about how it can be done on importing side : http://forum.dlang.org/post/pmezncogehwjnvjrxwns forum.dlang.org
Dec 03 2015
next sibling parent reply Dicebot <public dicebot.lv> writes:
And for that specific "stable" example - just make it a separate 
module, problem solved. To make use of module system for symbol 
resolution one needs to have many small modules, _that_ should 
become D idiom.
Dec 03 2015
next sibling parent reply Chris Wright <dhasenan gmail.com> writes:
On Thu, 03 Dec 2015 21:02:07 +0000, Dicebot wrote:

 And for that specific "stable" example - just make it a separate module,
 problem solved. To make use of module system for symbol resolution one
 needs to have many small modules, _that_ should become D idiom.
Usually the right answer, but then you get into circular dependency problems sometimes. You can fix circular dependency issues with deferred initialization, but that can muck up your API. You can fix them by moving static initialization into its own module, but that requires people to import the static initialization module. So maybe explicit namespaces within a module are justified sometimes.
Dec 03 2015
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 3 December 2015 at 21:46:03 UTC, Chris Wright wrote:
 So maybe explicit namespaces within a module are justified 
 sometimes.
I definitely think that there are times when it's justified, but I also think that they should be used sparingly. I think that the only time that I've used them is when conceptually I have a global object that I'm calling functions on but don't actually have an object - e.g. std.datetime.Clock has functions that get the time from the system clock, but the system clock is not an actual object, and std.windows.registry.Registry groups some windows registry-stuff in single, conceptual object. Though while conceptually I like having stuff like Clock.currTime, given that the monotonic clock stuff is separated into core.time with pretty much only the realtime clock stuff being in std.datetime, it doesn't work very well to have a single place to query the clock like that. So, much as I like it, having std.datetime.Clock was probably a mistake. Certainly, the only time that it makes sense to use a special namespace like this is when it makes sense to force the user to use the namespace every time they use the symbols in it rather than letting the module system differentiate things normally and let the user decide what they want to do. And there usually isn't a good reason to do that. - Jonathan M Davis
Dec 03 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-12-03 22:02, Dicebot wrote:
 And for that specific "stable" example - just make it a separate module,
 problem solved. To make use of module system for symbol resolution one
 needs to have many small modules, _that_ should become D idiom.
I agree. I will just be difficult to convince the core developers of that. -- /Jacob Carlborg
Dec 03 2015
next sibling parent ZombineDev <valid_email he.re> writes:
On Friday, 4 December 2015 at 07:12:50 UTC, Jacob Carlborg wrote:
 On 2015-12-03 22:02, Dicebot wrote:
 And for that specific "stable" example - just make it a 
 separate module,
 problem solved. To make use of module system for symbol 
 resolution one
 needs to have many small modules, _that_ should become D idiom.
I agree. I will just be difficult to convince the core developers of that.
The idea is about scoping of member functions. There's no way you can achieve this with modules, unless you're thinking of ruby modules and not D modules.
Dec 04 2015
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/04/2015 02:12 AM, Jacob Carlborg wrote:
 On 2015-12-03 22:02, Dicebot wrote:
 And for that specific "stable" example - just make it a separate module,
 problem solved. To make use of module system for symbol resolution one
 needs to have many small modules, _that_ should become D idiom.
I agree. I will just be difficult to convince the core developers of that.
How would one create a module inside a class or struct? -- Andrei
Dec 04 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-12-04 15:00, Andrei Alexandrescu wrote:

 How would one create a module inside a class or struct? -- Andrei
Hmm, I see that I really didn't understand what you were trying to do. So you want to create a namespace inside a class or struct? I would probably create a separate struct and return that from a function struct List(T) { static struct Stable { void fun(int x) { } } auto stable() { return Stable(); } } List!(int) list; list.stable.fun(2); -- /Jacob Carlborg
Dec 04 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jacob Carlborg <doob me.com> wrote:
 On 2015-12-04 15:00, Andrei Alexandrescu wrote:
 
 How would one create a module inside a class or struct? -- Andrei
Hmm, I see that I really didn't understand what you were trying to do. So you want to create a namespace inside a class or struct? I would probably create a separate struct and return that from a function struct List(T) { static struct Stable { void fun(int x) { } } auto stable() { return Stable(); } } List!(int) list; list.stable.fun(2);
Won't work. Fun has no access to the list.
Dec 04 2015
prev sibling next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Thursday, 3 December 2015 at 20:59:59 UTC, Dicebot wrote:
 This isn't any different from namespace struct idiom, is it? I 
 don't like it because it forces the namespace usage even if it 
 isn't needed. There is something wrong with the module system 
 if one needs to resort to idioms like this.

 My old finding about how it can be done on importing side : 
 http://forum.dlang.org/post/pmezncogehwjnvjrxwns forum.dlang.org
At work we started using abstract final classes a lot for this. #notashamed
Dec 03 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 3 December 2015 at 22:44:35 UTC, deadalnix wrote:
 At work we started using abstract final classes a lot for this.
which works just fine normally, but apparently, Andrei wants to namespace member functions within a class or struct, which means having access to a specific object of that class or struct, and as far as I can tell, there's no way to do that with a nested class or struct. - Jonathan M Davis
Dec 03 2015
prev sibling parent Mike <none none.com> writes:
On Thursday, 3 December 2015 at 22:44:35 UTC, deadalnix wrote:
 At work we started using abstract final classes a lot for this. 
 #notashamed
I used abstract final classes as well: https://github.com/JinShil/stm32f42_discovery_demo/blob/master/source/stm32f42/gpio.d. My use case is quite different, but it was the best method I could find for what I wanted to achieve. I actually would have preferred to use modules for my use case, but I couldn't get around the one-module-per-file limitation. That limitation seems rather arbitrary, so it may help with "namespacing" to remove that limitation. Mike
Dec 03 2015
prev sibling next sibling parent Mike <none none.com> writes:
On Thursday, 3 December 2015 at 20:59:59 UTC, Dicebot wrote:
 There is something wrong with the module system if one needs to 
 resort to idioms like this.
I agree. These techniques blur the line between "idiom" and "feature abuse". They're creative and sometimes the best or only option, but they're a red flag IMO. Mike
Dec 03 2015
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 12/3/2015 12:59 PM, Dicebot wrote:
 This isn't any different from namespace struct idiom, is it? I don't like it
 because it forces the namespace usage even if it isn't needed.
If you use mixin templates, you can use or not use the namespace. prefix.
Dec 03 2015
parent reply Dicebot <public dicebot.lv> writes:
On Friday, 4 December 2015 at 06:57:17 UTC, Walter Bright wrote:
 On 12/3/2015 12:59 PM, Dicebot wrote:
 This isn't any different from namespace struct idiom, is it? I 
 don't like it
 because it forces the namespace usage even if it isn't needed.
If you use mixin templates, you can use or not use the namespace. prefix.
True, that didn't come to my mind. But that pushes resulting coding style from "weird but tolerable" to "good luck explaining newbies why D modules are not broken". All for the sake of a putting a dot in the name. Look at perspective for a moment think if you would be happy to use a language which avdertises such approach as idiomatic (for one of most basic language operations).
Dec 04 2015
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 12/4/2015 12:48 AM, Dicebot wrote:
 True, that didn't come to my mind. But that pushes resulting coding style from
 "weird but tolerable" to "good luck explaining newbies why D modules are not
 broken". All for the sake of a putting a dot in the name. Look at perspective
 for a moment think if you would be happy to use a language which avdertises
such
 approach as idiomatic (for one of most basic language operations).
I don't understand your comment that modules are broken. With imports, you can use the module name as a prefix or not.
Dec 04 2015
next sibling parent reply Dicebot <public dicebot.lv> writes:
On Friday, 4 December 2015 at 09:30:08 UTC, Walter Bright wrote:
 I don't understand your comment that modules are broken. With 
 imports, you can use the module name as a prefix or not.
I am referring to Andrei proposal for template "namespaces" + your explanation of how it can be flattened via mixin. It works but advocating such means as idiomatic when there is existing module system (with named imports and stuff) sends a bad message about quality and applicability of such module system - especially considering it will be one of first things newbies see.
Dec 04 2015
parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/4/2015 1:35 AM, Dicebot wrote:
 On Friday, 4 December 2015 at 09:30:08 UTC, Walter Bright wrote:
 I don't understand your comment that modules are broken. With imports, you can
 use the module name as a prefix or not.
I am referring to Andrei proposal for template "namespaces" + your explanation of how it can be flattened via mixin. It works but advocating such means as idiomatic when there is existing module system (with named imports and stuff) sends a bad message about quality and applicability of such module system - especially considering it will be one of first things newbies see.
I argued against pseudo-namespaces.
Dec 04 2015
prev sibling parent reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Friday, 4 December 2015 at 09:30:08 UTC, Walter Bright wrote:
 On 12/4/2015 12:48 AM, Dicebot wrote:
 True, that didn't come to my mind. But that pushes resulting 
 coding style from
 "weird but tolerable" to "good luck explaining newbies why D 
 modules are not
 broken". All for the sake of a putting a dot in the name. Look 
 at perspective
 for a moment think if you would be happy to use a language 
 which avdertises such
 approach as idiomatic (for one of most basic language 
 operations).
I don't understand your comment that modules are broken. With imports, you can use the module name as a prefix or not.
The problem with using modules at this point is, as I come to same conclusion, that it forces name repetitions. Example I am defining many APIs right now for database operations. File is over thousand of lines, and each API is used for separate operations. I can create a separate module for each API to decrease complexity, but than both the name of module and name of API function are almost same thing. And, as it is very clearly seen in Phobos as well, many names are repeated again and again which creates ugly code. I even cannot propose any solution to this other then following the long way: using package.d to alias same function in both module and package which feels hackish. Andrei is, I guess, following that approach to prevent this as well.
Dec 04 2015
parent tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Friday, 4 December 2015 at 20:58:02 UTC, tcak wrote:
 On Friday, 4 December 2015 at 09:30:08 UTC, Walter Bright wrote:
 On 12/4/2015 12:48 AM, Dicebot wrote:
 [...]
I don't understand your comment that modules are broken. With imports, you can use the module name as a prefix or not.
The problem with using modules at this point is, as I come to same conclusion, that it forces name repetitions. Example I am defining many APIs right now for database operations. File is over thousand of lines, and each API is used for separate operations. I can create a separate module for each API to decrease complexity, but than both the name of module and name of API function are almost same thing. And, as it is very clearly seen in Phobos as well, many names are repeated again and again which creates ugly code. I even cannot propose any solution to this other then following the long way: using package.d to alias same function in both module and package which feels hackish. Andrei is, I guess, following that approach to prevent this as well.
Another solution of mine was to allow giving same name to multiple module files. So, compile would merge them as they are single. This would very easily solve the most name repetition problems. (There is a security risk here as overriding is possible, but I ignore it for now).
Dec 04 2015
prev sibling next sibling parent reply FreeSlave <freeslave93 gmail.com> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
I don't understand how it is namespace (it's just named scope for me) and why do we need template for that? Probably struct with static members would work the same without need for instantiating the template. When talking about namespaces in the C++ sense, the feature of namespace is that it can be scattered among many files and can be 'using'.
Dec 03 2015
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 04:05 PM, FreeSlave wrote:
 I don't understand how it is namespace (it's just named scope for me)
 and why do we need template for that? Probably struct with static
 members would work the same without need for instantiating the template.
How would one use a struct for the List example? There's no access to "this". Yes, it's a named scope.
 When talking about namespaces in the C++ sense, the feature of namespace
 is that it can be scattered among many files and can be 'using'.
Wasn't thinking of C++ namespaces specifically, just an interesting artifact. FWIW I wanted to use it to allow lst.linear.stable.insert() and lst.stable.linear.insert() to refer to the same function, but this is not working. Qualifies as a bug? template _pseudo_namespace() { void fun(int x) { import std.stdio; writeln(x); } } alias pseudo_namespace = _pseudo_namespace!(); struct List(T) { template _stable() { void insert(int x) { import std.stdio; writeln(x); } } alias stable = _stable!(); template _linear() { alias stable = _stable!(); } alias linear = _linear!(); } void main() { pseudo_namespace.fun(1); List!int lst; lst._stable!().insert(2); lst.stable.insert(2); lst._linear!().stable.insert(2); lst.linear.stable.insert(2); } Andrei
Dec 03 2015
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 3 December 2015 at 21:29:51 UTC, Andrei Alexandrescu 
wrote:
 On 12/03/2015 04:05 PM, FreeSlave wrote:
 I don't understand how it is namespace (it's just named scope 
 for me)
 and why do we need template for that? Probably struct with 
 static
 members would work the same without need for instantiating the 
 template.
How would one use a struct for the List example? There's no access to "this". Yes, it's a named scope.
You declare static functions on a struct or class and then make the struct or class unusable as an object (e.g. by having a final abstract class or explicitly disabling all ways to construct the struct or class). There are at least a couple of places in Phobos that do that already (e.g. std.windows.registry.Registry and std.datetime.Clock both use final classes with an disabled default constructor). - Jonathan M Davis
Dec 03 2015
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 05:14 PM, Jonathan M Davis wrote:
 You declare static functions on a struct or class and then make the
 struct or class unusable as an object (e.g. by having a final abstract
 class or explicitly disabling all ways to construct the struct or class).
I must be dense. Consider: struct List { int x; template _stable() { void fun() { import std.stdio; writeln(this.x); } } alias stable = _stable!(); } void main() { List lst; lst.stable.fun(); } Could you please redo the example with a struct? Thanks, Andrei
Dec 03 2015
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 3 December 2015 at 22:27:45 UTC, Andrei Alexandrescu 
wrote:
 On 12/03/2015 05:14 PM, Jonathan M Davis wrote:
 You declare static functions on a struct or class and then 
 make the
 struct or class unusable as an object (e.g. by having a final 
 abstract
 class or explicitly disabling all ways to construct the struct 
 or class).
I must be dense. Consider: struct List { int x; template _stable() { void fun() { import std.stdio; writeln(this.x); } } alias stable = _stable!(); } void main() { List lst; lst.stable.fun(); } Could you please redo the example with a struct?
Sorry, but I clearly didn't pay enough attention to what you were doing, because I only saw the namespace that you put at the module level and not the one inside of the struct. The one at the module level works just fine with a struct or class, avoids having to declare a alias, and allows you to just shove the documentation on the functions normally without having to explain that the functions in _MyNamespace need to be called with MyNamespace instead. It would also work inside of a class or struct except that based on the implementation of fun, you want access to the an object of the struct or class that it's in, and I don't see a way to do that anymore than you do. That being said, I confess that I don't see any reason to create namespaces inside of a struct or class. They already have to be used as part of the struct or class, so they're namespaced at that level already, and if you have so many member functions that you feel the need to namespace them further, then that implies that you have way too many IMHO. But you can always just put the "namespace" in their names. It's even one character shorter, because you avoid the period. - Jonathan M Davis
Dec 03 2015
prev sibling parent ZombineDev <valid_email he.re> writes:
On Thursday, 3 December 2015 at 22:14:56 UTC, Jonathan M Davis 
wrote:
 On Thursday, 3 December 2015 at 21:29:51 UTC, Andrei 
 Alexandrescu wrote:
 On 12/03/2015 04:05 PM, FreeSlave wrote:
 [...]
How would one use a struct for the List example? There's no access to "this". Yes, it's a named scope.
You declare static functions on a struct or class and then make the struct or class unusable as an object (e.g. by having a final abstract class or explicitly disabling all ways to construct the struct or class). There are at least a couple of places in Phobos that do that already (e.g. std.windows.registry.Registry and std.datetime.Clock both use final classes with an disabled default constructor). - Jonathan M Davis
Why would you need to resort to such hackery, when Andrei's solution is much more cleaner?
Dec 03 2015
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/03/2015 10:29 PM, Andrei Alexandrescu wrote:
 FWIW I wanted to use it to allow lst.linear.stable.insert() and
 lst.stable.linear.insert() to refer to the same function, but this is
 not working. Qualifies as a bug?
Yes. (It works with my own implementation of name lookup.)
Dec 03 2015
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/3/2015 1:29 PM, Andrei Alexandrescu wrote:
 FWIW I wanted to use it to allow lst.linear.stable.insert() and
 lst.stable.linear.insert() to refer to the same function, but this is not
 working. Qualifies as a bug?
I don't want this to become a D idiom. It's too clever, too confusing, too verbose, and nobody knows how it is supposed to work.
Dec 03 2015
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/3/2015 1:05 PM, FreeSlave wrote:
 When talking about namespaces in the C++ sense, the feature of namespace is
that
 it can be scattered among many files and can be 'using'.
I call that a bug, not a feature, since one loses all control over overloading of names and encapsulation. If you're going to do that, it's better to simply use _ instead of . namespace_name instead of: namespace.name
Dec 03 2015
prev sibling next sibling parent ZombineDev <valid_email he.re> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
I think this is a nice trick, but DDOC would need to support it for it be useful for API discovery.
Dec 03 2015
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/3/15 3:51 PM, Andrei Alexandrescu wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has anyone
 explored it? Is it a viable candidate for becoming a D idiom?
I'm going to take a step back and ask, what's wrong with stableFun? -Steve
Dec 03 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 05:46 PM, Steven Schveighoffer wrote:
 On 12/3/15 3:51 PM, Andrei Alexandrescu wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has anyone
 explored it? Is it a viable candidate for becoming a D idiom?
I'm going to take a step back and ask, what's wrong with stableFun?
Nothing. But one thing I was keeping an eye for would be to allow lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
Dec 03 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/3/15 5:54 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:46 PM, Steven Schveighoffer wrote:
 On 12/3/15 3:51 PM, Andrei Alexandrescu wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has anyone
 explored it? Is it a viable candidate for becoming a D idiom?
I'm going to take a step back and ask, what's wrong with stableFun?
Nothing. But one thing I was keeping an eye for would be to allow lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
alias stableLinearXxx = linearStableXxx; -Steve
Dec 03 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
Dec 03 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/3/15 8:01 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
To what? How many nested namespaces are you planning? -Steve
Dec 03 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 08:59 PM, Steven Schveighoffer wrote:
 On 12/3/15 8:01 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
To what? How many nested namespaces are you planning?
Many functions, not many namespaces. One declaration per function is fail. -- Andrei
Dec 03 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/3/15 9:20 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 08:59 PM, Steven Schveighoffer wrote:
 On 12/3/15 8:01 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
To what? How many nested namespaces are you planning?
Many functions, not many namespaces. One declaration per function is fail. -- Andrei
It seems worse with namespaces: 1. a linear namespace 2. a sub namespace for linear.stable 3. a function definition for linear.stable.foo 4. a stable namespace 5. a sub namespace for stable.linear 6. an alias (I'm assuming you're not repeating the function definition here) for stable.linear.foo to linear.stable.foo Perhaps my strawman isn't what you were thinking, let me know. It appears to me that you will need more machinery for namespaces. -Steve
Dec 03 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 09:37 PM, Steven Schveighoffer wrote:
 On 12/3/15 9:20 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 08:59 PM, Steven Schveighoffer wrote:
 On 12/3/15 8:01 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
To what? How many nested namespaces are you planning?
Many functions, not many namespaces. One declaration per function is fail. -- Andrei
It seems worse with namespaces: 1. a linear namespace 2. a sub namespace for linear.stable 3. a function definition for linear.stable.foo 4. a stable namespace 5. a sub namespace for stable.linear 6. an alias (I'm assuming you're not repeating the function definition here) for stable.linear.foo to linear.stable.foo Perhaps my strawman isn't what you were thinking, let me know. It appears to me that you will need more machinery for namespaces. -Steve
I don't get your point. Mine is there are many methods and few named scopes aka namespaces. So I'm okay to scale declarations linearly with number of named scopes but not with number of methods. -- Andrei
Dec 03 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/3/15 9:40 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 09:37 PM, Steven Schveighoffer wrote:
 On 12/3/15 9:20 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 08:59 PM, Steven Schveighoffer wrote:
 On 12/3/15 8:01 PM, Andrei Alexandrescu wrote:
 On 12/03/2015 05:59 PM, Steven Schveighoffer wrote:
 alias stableLinearXxx = linearStableXxx;
Doesn't scale. -- Andrei
To what? How many nested namespaces are you planning?
Many functions, not many namespaces. One declaration per function is fail. -- Andrei
It seems worse with namespaces: 1. a linear namespace 2. a sub namespace for linear.stable 3. a function definition for linear.stable.foo 4. a stable namespace 5. a sub namespace for stable.linear 6. an alias (I'm assuming you're not repeating the function definition here) for stable.linear.foo to linear.stable.foo Perhaps my strawman isn't what you were thinking, let me know. It appears to me that you will need more machinery for namespaces.
I don't get your point. Mine is there are many methods and few named scopes aka namespaces. So I'm okay to scale declarations linearly with number of named scopes but not with number of methods. -- Andrei
I think I see, all you need is a way to generate the aliases that will be both linear and stable. I can think of nasty ways to do this with opDispatch. FWIW, I don't believe this complexity of API is worth it. It may be you have all this wonderful mechanisms to specify exactly the runtime requirements for your algorithms -- and nobody uses it because they either a) have a specific container in mind, or b) don't care to constrain the container type being used. I think there are a few basic guarantees to worry about, and anything beyond that is overcomplicating things. -Steve
Dec 03 2015
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 09:59 PM, Steven Schveighoffer wrote:
 FWIW, I don't believe this complexity of API is worth it.
It's essential. -- Andrei
Dec 03 2015
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= writes:
On Friday, 4 December 2015 at 02:59:12 UTC, Steven Schveighoffer 
wrote:
 FWIW, I don't believe this complexity of API is worth it. It 
 may be you have all this wonderful mechanisms to specify 
 exactly the runtime requirements for your algorithms -- and
Big-Oh isn't particularly useful, but having an upper bound on actual running time is useful in real time programming. What would be more useful is to have the compiler infer worst case number of cycles or operations or cachelines affected, whether it allocates or not, whether it can lock, whether it can result in system calls etc. I don't think the handwritten documentation is all that useful, but measured performance using a test suite on a given architecture could be very useful!
Dec 04 2015
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= writes:
On Friday, 4 December 2015 at 08:40:13 UTC, Ola Fosheim Grøstad 
wrote:
 Big-Oh isn't particularly useful, but having an upper bound on 
 actual running time is useful in real time programming.
And to avoid confusion: in real time applications _everything_ is O(1). Anything worse than that is non-real-time.
Dec 04 2015
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 3 December 2015 at 22:54:53 UTC, Andrei Alexandrescu 
wrote:
 On 12/03/2015 05:46 PM, Steven Schveighoffer wrote:
 On 12/3/15 3:51 PM, Andrei Alexandrescu wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone
 explored it? Is it a viable candidate for becoming a D idiom?
I'm going to take a step back and ask, what's wrong with stableFun?
Nothing. But one thing I was keeping an eye for would be to allow lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
That seems like it would be confusing, since it's non-obvious that those two things would be the same thing, though there also isn't an obvious hierarchy between linear and stable. AFAIK, they're orthogonal, so it's not obvious which would go inside the other. However, it also doesn't seem very user friendly to have that much extra stuff involved in what is essentially the function name. Whether it's using pseudo-namespaces or is just one long name, linearStableXXX / linear.stable.xxx and stableLinearXXX / stable.linear.xxx are both rather unwieldy, though I confess that I prefer not having the periods. It's shorter that way, and you don't have to explain the pseudo-namespaces to anyone that way either, since that's not exactly a normal idiom. But it would be best IMHO if we could find a way to either not need those extra tags on the function names or to at least minimze their length. - Jonathan M Davis
Dec 03 2015
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-12-03 23:54, Andrei Alexandrescu wrote:

 Nothing. But one thing I was keeping an eye for would be to allow
 lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
How do you plan to differentiate the functionality? -- /Jacob Carlborg
Dec 03 2015
prev sibling next sibling parent reply Minas Mina <minas_0 hotmail.co.uk> writes:
On Thursday, 3 December 2015 at 22:54:53 UTC, Andrei Alexandrescu 
wrote:
 Nothing. But one thing I was keeping an eye for would be to 
 allow lst.stable.linear.xxx and lst.linear.stable.xxx with one 
 body. -- Andrei
Please don't. Choose one to be the outer and one to be the inner. Otherwise people will sometimes use one, sometimes the other and code will look inconsistent. Just choose one.
Dec 03 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/04/2015 02:19 AM, Minas Mina wrote:
 On Thursday, 3 December 2015 at 22:54:53 UTC, Andrei Alexandrescu wrote:
 Nothing. But one thing I was keeping an eye for would be to allow
 lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
Please don't. Choose one to be the outer and one to be the inner. Otherwise people will sometimes use one, sometimes the other and code will look inconsistent. Just choose one.
Sensible, dziękuję. -- Andrei
Dec 04 2015
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 12/3/2015 2:54 PM, Andrei Alexandrescu wrote:
 But one thing I was keeping an eye for would be to allow
 lst.stable.linear.xxx and lst.linear.stable.xxx with one body. -- Andrei
lst.xxx!(stable, linear)
Dec 03 2015
prev sibling next sibling parent Meta <jared771 gmail.com> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
Walter doesn't like it but there's always this option as well. IMO it's the cleanest way: extern(C++, stable.linear) { extern(D): enum sort = 0; } extern(C++, linear.stable) { extern(D): alias sort = .stable.linear.sort; } void main() { assert(stable.linear.sort == 0); assert(linear.stable.sort == 0); }
Dec 03 2015
prev sibling next sibling parent reply Idan Arye <GenericNPC gmail.com> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
People are going to hate me, but http://dpaste.dzfl.pl/851d1d1f5e4b
Dec 03 2015
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 08:04 PM, Idan Arye wrote:
 People are going to hate me, but http://dpaste.dzfl.pl/851d1d1f5e4b
Win :o). -- Andrei
Dec 03 2015
parent reply Tofu Ninja <emmons0 purdue.edu> writes:
On Friday, 4 December 2015 at 01:09:07 UTC, Andrei Alexandrescu 
wrote:
 On 12/03/2015 08:04 PM, Idan Arye wrote:
 People are going to hate me, but 
 http://dpaste.dzfl.pl/851d1d1f5e4b
Win :o). -- Andrei
Not win, we should feel ashamed that this is the kind of stuff you have to do.
Dec 03 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/03/2015 08:52 PM, Tofu Ninja wrote:
 On Friday, 4 December 2015 at 01:09:07 UTC, Andrei Alexandrescu wrote:
 On 12/03/2015 08:04 PM, Idan Arye wrote:
 People are going to hate me, but http://dpaste.dzfl.pl/851d1d1f5e4b
Win :o). -- Andrei
Not win, we should feel ashamed that this is the kind of stuff you have to do.
I'm running out of shame over here. -- Andrei
Dec 03 2015
prev sibling parent reply Mike <none none.com> writes:
On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but 
 http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
Dec 03 2015
next sibling parent Idan Arye <GenericNPC gmail.com> writes:
On Friday, 4 December 2015 at 01:37:35 UTC, Mike wrote:
 On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but 
 http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
Yea, my bad. Initially I used a template mixin, but the syntax was ugly so I changed it to a regular template + alias. When you use a template mixin member access does work: http://dpaste.dzfl.pl/9ca85cbecea7
Dec 03 2015
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/04/2015 02:37 AM, Mike wrote:
 On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
template namespace(string code,alias a=void){ mixin(code); } struct List{ int x; alias stable = namespace!(q{ void fun(){ import std.stdio; writeln(this.x); } },x); } void main(){ List lst; lst.stable.fun(); } :o)
Dec 03 2015
parent reply Tofu Ninja <emmons0 purdue.edu> writes:
On Friday, 4 December 2015 at 02:02:48 UTC, Timon Gehr wrote:
 On 12/04/2015 02:37 AM, Mike wrote:
 On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but 
 http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
template namespace(string code,alias a=void){ mixin(code); } struct List{ int x; alias stable = namespace!(q{ void fun(){ import std.stdio; writeln(this.x); } },x); } void main(){ List lst; lst.stable.fun(); } :o)
WTF! Why does that even work! That is strait madness! When the code gets mixed into the namespace template, x would have been re-aliased to a, it would have made sense to write "writeln(a)" which works as well... but "writeln(this.x)", wut, how... that makes no sense...
Dec 03 2015
next sibling parent Tofu Ninja <emmons0 purdue.edu> writes:
On Friday, 4 December 2015 at 02:24:32 UTC, Tofu Ninja wrote:
 On Friday, 4 December 2015 at 02:02:48 UTC, Timon Gehr wrote:
 On 12/04/2015 02:37 AM, Mike wrote:
 On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but 
 http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
template namespace(string code,alias a=void){ mixin(code); } struct List{ int x; alias stable = namespace!(q{ void fun(){ import std.stdio; writeln(this.x); } },x); } void main(){ List lst; lst.stable.fun(); } :o)
WTF! Why does that even work! That is strait madness! When the code gets mixed into the namespace template, x would have been re-aliased to a, it would have made sense to write "writeln(a)" which works as well... but "writeln(this.x)", wut, how... that makes no sense...
WTF, some how having an alias to x passed in, brings the entire this along with it. This works equally as well.... struct List{ int x; int y; alias stable = namespace!(q{ void fun(){ import std.stdio; writeln(typeid(this)); writeln(this.x + this.y); } },x); }
Dec 03 2015
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 12/04/2015 03:24 AM, Tofu Ninja wrote:
 On Friday, 4 December 2015 at 02:02:48 UTC, Timon Gehr wrote:
 On 12/04/2015 02:37 AM, Mike wrote:
 On Friday, 4 December 2015 at 01:04:33 UTC, Idan Arye wrote:
 People are going to hate me, but http://dpaste.dzfl.pl/851d1d1f5e4b
Doesn't seem to scale to member access: http://dpaste.dzfl.pl/37193377524c /d649/f987.d-mixin-3(7): Error: 'this' is only defined in non-static member functions, not fun Is there a way to make it work? Mike
template namespace(string code,alias a=void){ mixin(code); } struct List{ int x; alias stable = namespace!(q{ void fun(){ import std.stdio; writeln(this.x); } },x); } void main(){ List lst; lst.stable.fun(); } :o)
WTF! Why does that even work! That is strait madness! When the code gets mixed into the namespace template, x would have been re-aliased to a, it would have made sense to write "writeln(a)" which works as well... but "writeln(this.x)", wut, how... that makes no sense...
http://dlang.org/spec/template.html#nested-templates "If a template has a template alias parameter, and is instantiated with a local symbol, the instantiated function will implicitly become nested in order to access runtime data of the given local symbol." You are probably relying on this feature in a significant portion of your code, especially for lambda template arguments. It does not really cover all cases where one would like to have nested instantiation though.
Dec 03 2015
prev sibling parent Tofu Ninja <emmons0 purdue.edu> writes:
On Thursday, 3 December 2015 at 20:51:02 UTC, Andrei Alexandrescu 
wrote:
 I vaguely remembered I saw something like this a while ago:

 http://dpaste.dzfl.pl/f11894a098c6

 The trick could be more fluent, but it might have merit. Has 
 anyone explored it? Is it a viable candidate for becoming a D 
 idiom?

 I was looking at this in conjunction with choosing a naming 
 convention for container functions. Some functions are "stable" 
 so that would be part of their name, e.g. insertStable or 
 stableInsert. With this, it's possible to write 
 lst.stable.insert.


 Andrei
Honestly I feel like scoping in D is kinda broken. IMO they need to be cleaned up a bit, with some kind of meaningful formalization of scopes, how to interact with them properly and what not. Also I think to do what you want with out fragile hacks would require some type of named scope concept added to the language. Lots of things in the language introduce scopes, but there is no formalization on them. Modules, packages, named template instantiations, named mixin templates, structs, classes, unions, and anonymous scopes with {}. But it seems like they all have slightly different rules. There are a lot of things that have scopes but opDispatch only works on classes and structs, why? opDispatch is a scope thing, not a class or struct thing. Mixin templates have weird as fuck scope rules as well, and really should never have been added to the language. {} in a function introduces a scope but I cant name it. In a template if it has a member with the name as the template, the instantiation forwards to that member, but in structs alias this servers a similar purpose. All these things should be related with some kind of formalized scope concept. I should be able to do "alias scopeName = { // scope stuff };" or "int scopeName.foo = 5;". Or in your problem, "void stable.fun() {...}". Also any scope should be able to have an opDispatch. Scopes are a bit fucked up in D. Bit of a rant, sorry..
Dec 03 2015