Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 16:05:35 UTC, Satoshi wrote: Sorry, but D seems to be worse and worse day by day. This should be resolved by language and not doing it by template function. Same thing should be applied for maybe monad and tuples. I'm reminded of trying to follow the rules and do both L types, and I came across unwanted behavior since the qualifiers would make something the wrong type because constness was closer matching, among other weird behavior. I'll hope more of this gets resolved, and then I can look at the language seriously and really do something with it.
Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 22:03:14 UTC, Satoshi wrote: or I have simple class class View { this(Rectangle frame) {...} this(float, float, float, float) { ... } this(Point, Size) { ... } } then struct Point, Size and Rectangle (Point, Size) now I need to write 2 overloads for View class taking 4 floats or (Point, Size) and this must do in every descendant of View class. This can be solved with string-mixins.
Re: Const/Immutable Slicing Syntax
cast(const) x[]; cast(immutable) x[];
Re: A simplification of the RvalueRef idiom
On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: mixin template RvalueRef()// <-- DOES NOT TAKE A PARAMETER ANY MORE { alias T = typeof(this); static assert (is(T == struct)); @nogc @safe ref const(T) byRef() const pure nothrow return Why do you need to qualify `byRef` as pure nothrow when it's a template?
Re: A simplification of the RvalueRef idiom
On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: Let me know if it's not the equivalent of the original. Ali Nice. What about putting this in a druntime or phobos PR, making it standardized?
Re: Char representation
On Tuesday, 22 November 2016 at 13:29:47 UTC, RazvanN wrote: Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug? When seen as a range the element type of a char[] is indeed dchar. This is autodecoding at work.
Get return type of a template function without instantiating it
Is there a way to get a template function return type with instantiating it? The return type is independent of the template arguments. I'm asking because there's potentially recursive template instantiation if I do try to instantiate it.
Char representation
Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug?
Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 13:06:27 UTC, Nordlöw wrote: On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: mixin template RvalueRef()// <-- DOES NOT TAKE A PARAMETER ANY MORE { alias T = typeof(this); static assert (is(T == struct)); @nogc @safe ref const(T) byRef() const pure nothrow return Why do you need to qualify `byRef` as pure nothrow when it's a template? No need for these, but I did it out of habit ;)
Re: A simplification of the RvalueRef idiom
On 11/22/2016 05:06 AM, Nordlöw wrote: On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: mixin template RvalueRef()// <-- DOES NOT TAKE A PARAMETER ANY MORE { alias T = typeof(this); static assert (is(T == struct)); @nogc @safe ref const(T) byRef() const pure nothrow return Why do you need to qualify `byRef` as pure nothrow when it's a template? I don't think you need those. I didn't pay attention to any other part of the code other than moving that parameter inside. :) Ali
Re: Char representation
Dne 22.11.2016 v 14:29 RazvanN via Digitalmars-d-learn napsal(a): Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug? https://dlang.org/library/std/range/primitives/element_encoding_type.html
Re: Char representation
Dne 22.11.2016 v 14:29 RazvanN via Digitalmars-d-learn napsal(a): Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug? RTFM: https://dlang.org/library/std/range/primitives/element_type.html
Re: Get return type of a template function without instantiating it
On Tuesday, 22 November 2016 at 12:21:18 UTC, Yuxuan Shui wrote: Is there a way to get a template function return type with instantiating it? The return type is independent of the template arguments. I'm asking because there's potentially recursive template instantiation if I do try to instantiate it. Do you control the template in question's source? If so you could have a degenerate template type (e.g. MyTemplate!void ) that just returns the correct types .init Otherwise i'm not sure you can because IIRC std.traits.ReturnType requires an instantiated symbol.
Re: Get return type of a template function without instantiating it
On Tuesday, 22 November 2016 at 12:21:18 UTC, Yuxuan Shui wrote: Is there a way to get a template function return type with instantiating it? The return type is independent of the template arguments. I'm asking because there's potentially recursive template instantiation if I do try to instantiate it. What you want cannot work in the general case. The template function must be instantiated. T identity(T)(T t) { return t; } It's not possible to calculate the type of the return value of `identity` until it is instantiated with a type.
Re: Get return type of a template function without instantiating it
On Tuesday, November 22, 2016 12:21:18 Yuxuan Shui via Digitalmars-d-learn wrote: > Is there a way to get a template function return type with > instantiating it? The return type is independent of the template > arguments. No. There _is_ no function unless the template is instantiated. Remember that a templated function such as auto foo(T)(T t) if(cond) { ... } gets lowered to template foo(T) if(cond) { auto foo(T t) { ... } } Without instantiating the template, _nothing_ within the template actually exists except with regards to documentation generation. Not even the unittest blocks inside of a templated type exist until the type is instantiated. A template is just that - a template for code - not actual code to run, examine, or infer stuff from. It's only instantiations of the template that can be run, examined, or have stuff inferred about them. > I'm asking because there's potentially recursive template > instantiation if I do try to instantiate it. If you want to avoid a recursive instantiation, then use a static if inside the template to break the recursion. - Jonathan M Davis
Re: Char representation
On 23/11/2016 2:29 AM, RazvanN wrote: Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug? "For example, ElementType!(T[]) is T if T[] isn't a narrow string; if it is, the element type is dchar"[0]. [0] https://dlang.org/phobos/std_range_primitives.html#ElementType
Re: A simplification of the RvalueRef idiom
On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: ref const(T) byRef() const pure nothrow return Add when DIP-1000 has been implemented into compiler this should be `scope`-qualified aswell, right?
Re: Char representation
On Tuesday, 22 November 2016 at 13:29:47 UTC, RazvanN wrote: Is this a bug? The language is sane. The standard library is not alas, it is insane by design, so not a bug.
Re: How to muldiv in D?
Yep, I need muldiv for long values on x86-64.
Const/Immutable Slicing Syntax
What's the cleanest way of doing const or immutable slicing in D? My first thought is cast((const typeof(x))x)[] cast((immutable typeof(x))x)[] but that's too verbose for my/taste. Is there a Phobos function for this?
mqtt client id
hi, I am totally following what hivemq and mqtt specs are telling.But i have confusion regarding their implementation.In mqtt specs they are suggesing to generate random client id if cleansession flag is true and not for cleansession flag being false.My question is how do i really implement this on my area of programming language.To be more specific am working in linux command line and my programming language is c++.
Re: Is there a way to identfy Windows version?
On Monday, 21 November 2016 at 09:11:39 UTC, Jonathan M Davis wrote: On Monday, November 21, 2016 08:57:11 Bauss via Digitalmars-d-learn wrote: [...] Phobos doesn't have anything like that, but you can use the C functions from the Windows API to do it. A quick search turned up GetVersion and GetVersionExA/W: [...] Thank you, I thought I would end up with something like that! :)
Re: How to muldiv in D?
On Tuesday, 22 November 2016 at 08:54:36 UTC, Kagamin wrote: Yep, I need muldiv for long values on x86-64. Quick and dirty assembler: version(D_InlineAsm_X86_64): long muldiv(long a, long b, long c) { //windows RCX, RDX, R8 //linux RDI, RSI, RDX version(Windows) { asm { naked; mov RAX, RCX; //RAX = a imul RDX; //RDX:RAX = a * b idiv R8;//RAX = a * b / c ret; } } else version(linux) { asm { naked; mov RAX, RDI; //RAX = a; mov R8, RDX;//R8 = b imul RSI; //RDX:RAX = a * b idiv R8;//RAX = a * b / c ret; } } else static assert(0); }
Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 19:16:56 UTC, Ali Çehreli wrote: On 11/22/2016 08:05 AM, Satoshi wrote: I don't have extensive experience with other languages. In fact, the only other languages that I can claim proficiency are C and C++. (I also know Python just enough to find it incredible how it's used in the industry. Let's not get in to that discussion but I really tried and failed... in industry... :) ) Given that experience, I still find D a very useful tool. D is one o the best languages what exists, it's reason why I'm using it. But some issues are solved better in other languages like rust, go or swift. Agreed but it opens the door for bugs. Assuming struct A { int a; } struct B { int b; int c; } void foo(int, int, int); If foo(1, 2, 3) meant foo(A(1), B(2, 3)) today, it could silently mean foo(A(1, 2), B(3)) if one moved one member from one struct to the other. Then there are other corner cases: writeln(1, 2, 3); Should that print the integers or A(1) and B(2, 3)? It's always better to be explicit. argument expand should be applied only to the last argument and cannot be used in variadic templates. Like in my simple example where I exactly know what function will do, but I want to call it by simplest way. It actually works with classes, but no with structs. import std.stdio; struct Point { int x; int y; } struct GraphicsContext { static GraphicsContext current() { return GraphicsContext(); } void moveTo(Point point) { writefln("Moving to %s", point); } void lineTo(Point point) { writefln("Drawing line to %s", point); } } void goTo(GraphicsContext gc, int x, int y) { gc.moveTo(Point(x, y)); } void drawTo(GraphicsContext gc, int x, int y) { gc.lineTo(Point(x, y)); } void main() { auto gc = GraphicsContext.current; gc.goTo(70, 70);// <-- Clean syntax gc.drawTo(70, 170); } But I need to write overload function for every function taking simple messengers like Point/Size/Rectangle
Re: Char representation
On Tuesday, 22 November 2016 at 14:23:28 UTC, Jonathan M Davis wrote: On Tuesday, November 22, 2016 13:29:47 RazvanN via Digitalmars-d-learn wrote: [...] You misunderstand. char[] is a dynamic array of char, wchar[] is a dynamic array of wchar[], and dchar[] is a dynamic array of dchar. There is nothing funny going on with the internal representation. Rather, the problem is with the range API and the traits that go with it. And it's not a bug; it's a design mistake. [...] Thank you very much for this great explanation. Things are starting to make sense now. Razvan Nitu
Re: A simplification of the RvalueRef idiom
On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: Let me know if it's not the equivalent of the original. Ali I've changed the idiom, thanks. The place to discuss this is the d-idioms bugtracker, else I would have skipped this message.
Re: Char representation
On Tuesday, November 22, 2016 13:29:47 RazvanN via Digitalmars-d-learn wrote: > Given the following code: > > char[5] a = ['a', 'b', 'c', 'd', 'e']; > alias Range = char[]; > writeln(is(ElementType!Range == char)); > > One would expect that the program will print true. In fact, it > prints false and I noticed that if Range is char[], wchar[], > dchar[], string, wstring, dstring > Unqual!(ElementType!Range) is dchar. I find it odd that the > internal representation for char and string is dchar. Is this a > bug? You misunderstand. char[] is a dynamic array of char, wchar[] is a dynamic array of wchar[], and dchar[] is a dynamic array of dchar. There is nothing funny going on with the internal representation. Rather, the problem is with the range API and the traits that go with it. And it's not a bug; it's a design mistake. I don't know how much you know about Unicode, but for a quick explanation, you have code units, code points, and graphemes. A grapheme is made up of one or more code points, and a code point is made up of one or more code units. In the case of UTF-8, a code unit is 8 bits; in UTF-16, a code unit is 16 bits; and in UTF-32, a code unit is 32 bits. Those are represented in D by char, wchar, dchar respectively. There is no guarantee that a char, wchar, or dchar is a representable character. A code unit is just a piece of a character except in the cases where it happens to be a full character. :| A code point, on the other hand, actually makes up something composable and printable. It's something like the letter A, or é, or, の, etc. It could also be an accent, a superscript, subscript, etc. In the case of UTF-8 and UTF-16, it can take several code units to form a single code point. In the case of UTF-32, a single code unit is always a code point, because code points take up 32 bits. However, that's still not necessarily a full character. After all, an accent or a superscript is not really a character. Rather, it's a modifier for a character. So, one or more code points can be combined to form graphemes which _are_ actual characters. Unfortunately, there are several normalization schemes for the order of code points in a grapheme, and some graphemes can be represented as a single code point or as several (most notably, the characters which commonly have accents on them such as é come both as single code points and as combined code points). So, this whole thing gets stupidly complicated. It's even worse when you want to handle it all _efficiently_. Well, when Andrei added ranges to D, he tried to simplify things so that the default was correct and reasonably efficient while allowing for code to specialize where appropriate to get the full efficiency. That's a noble goal, but unfortunately, he didn't know about graphemes at the time. He thought that code points were guaranteed to be full characters and that if you operated at the code point level, you were guaranteed full correctness. So, in order to avoid errors related to chopping up strings of char or wchar in the middle of code points, he came up with the concept of "narrow" strings - i.e. strings which are made up of char or wchar rather than dchar (so strings where each code unit is not guaranteed to be a code point), and he restricted what narrow strings could do by default per the range API and its associated traits. So, we get fun like this. assert(!hasLength!string); assert(!hasLength!wstring); assert(hasLength!dstring); assert(!isRandomAccessRange!string); assert(!isRandomAccessRange!wstring); assert(isRandomAccessRange!dstring); assert(is(ElementType!string == dchar)); assert(is(ElementType!wstring == dchar)); assert(is(ElementType!dstring == dchar)); And front, popFront, back, and popBack all automatically decode the code units in a string to code points. So, front and back both return dchar even if the string is a string of char or wchar. The arrays themselves do not change. However, the way that the traits in std.range.primitives treat them is then fundamentally different from how the language treats them. So, even though string str = "hello world"; for(auto r = str; !r.empty; r.popFront()) { auto e = range.front; } will iterate by dchar string str = "hello world"; foreach(e; str) { } will iterate by char. If you want it to iterate by dchar, then you make it explicit. string str = "hello world"; foreach(dchar e; str) { } The result of all of this is that by default, when you treat strings as ranges, you operate at the code point level. This avoids certain bugs where code would otherwise chop up code points by operating on code units, but since it doesn't actually go to the grapheme level, it still isn't actually correct, and it's easier to miss the fact that it's wrong, since more cases work. It's also inefficient, because the code units are always decoded to code points regardless of whether the algorithm in question actually needs to do that or not. It also creates confusion and questions like yours.
Re: A simplification of the RvalueRef idiom
On Monday, 21 November 2016 at 20:04:51 UTC, Ali Çehreli wrote: First, a reminder that we have this great resource of D idioms: https://p0nce.github.io/d-idioms/#Rvalue-references:-Understanding-auto-ref-and-then-not-using-it The link above has an idiom of mixing in a byRef() member function to a struct. I think I've simplified the template by moving typeof(this) inside it: mixin template RvalueRef()// <-- DOES NOT TAKE A PARAMETER ANY MORE { alias T = typeof(this); static assert (is(T == struct)); @nogc @safe ref const(T) byRef() const pure nothrow return { return this; } } struct Vector2f { float x, y; this(float x, float y) pure nothrow { this.x = x; this.y = y; } mixin RvalueRef;// <-- SIMPLER USE } void foo(ref const Vector2f pos) { writefln("(%.2f|%.2f)", pos.x, pos.y); } void main() { Vector2f v = Vector2f(42, 23); foo(v); // Works foo(Vector2f(42, 23).byRef); // Works as well, and use the same function } Let me know if it's not the equivalent of the original. Ali Sorry, but D seems to be worse and worse day by day. This should be resolved by language and not doing it by template function. Same thing should be applied for maybe monad and tuples. e.g. When I want to create simple function for drawing void lineTo(auto ref Point point...) { //... } It's easier to call it like: Point p = Point(42, 42); lineTo(p); lineTo(42, 42); lineTo(Point(42, 42)); // this lineTo(Point(42, 42).byRef); // and this is just overhead Everything possible should be solved by syntactic sugar rather than implementing it as template func. Or just remove shared, TLS and other stuff from D and implement it as templates like in C++. Then you can write much more longer and uglier stuffs as you trying. void lineTo(std::shared_ptr point) { // ... } lineTo(std::make(42, 42)); should be ideal way how to complicate programming for other users. Sorry, but I want to write fast and safe programs in the fastest possible way and writing Point(...) or Point(...).byRef every time is redundant overhead. Like http://pix.toile-libre.org/upload/original/1479816672.png PS: sorry for sarcasm - Satoshi
Re: Is there a way to identfy Windows version?
On Tuesday, 22 November 2016 at 11:00:52 UTC, Bauss wrote: On Monday, 21 November 2016 at 09:11:39 UTC, Jonathan M Davis wrote: On Monday, November 21, 2016 08:57:11 Bauss via Digitalmars-d-learn wrote: [...] Phobos doesn't have anything like that, but you can use the C functions from the Windows API to do it. A quick search turned up GetVersion and GetVersionExA/W: [...] Thank you, I thought I would end up with something like that! :) Obtaining the true Windows version is tricky starting with Windows 8. Be careful when using GetVersionEx, it's deprecated. VerifyVersionInfo is more reliable, but it will not return a version greater than Windows 8 if your application does not embed a specific manifest. The dirty way to obtain the true Windows version without embedding a manifest, it's to check for the availability of specific functions. Another way is to parse HLKM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Product Name. And finally NetServerGetInfo is your best bet, but it's not guaranteed to work in the future version of Windows.
Re: Memory allocation failed. Why?
On 11/21/16 11:53 AM, ag0aep6g wrote: On Monday, 21 November 2016 at 16:37:32 UTC, Kagamin wrote: Anything in .data and .bss sections and stack. See https://issues.dlang.org/show_bug.cgi?id=15723 Ok, not an actual reference then, but a false pointer. Yes. 100 million bytes is 1/40 of all addressable space on 32-bits. There only needs to be one 4-byte segment somewhere on the stack that points at this, and it won't be collected. Assuming you have a quite large segment that can't be extended or collected (due to false pointer), this means you have to allocate another large one to satisfy the next allocation (which then could be pinned). And it gets worse from there. -Steve
Re: Char representation
On Tuesday, 22 November 2016 at 13:29:47 UTC, RazvanN wrote: Given the following code: char[5] a = ['a', 'b', 'c', 'd', 'e']; alias Range = char[]; writeln(is(ElementType!Range == char)); One would expect that the program will print true. In fact, it prints false and I noticed that if Range is char[], wchar[], dchar[], string, wstring, dstring Unqual!(ElementType!Range) is dchar. I find it odd that the internal representation for char and string is dchar. Is this a bug? Here's the reading: https://forum.dlang.org/post/nh2o9i$hr0$1...@digitalmars.com
Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 16:05:35 UTC, Satoshi wrote: Sorry, but D seems to be worse and worse day by day. This should be resolved by language and not doing it by template function. I hate this 'idiom' too (just a clumsy workaround for something that should work out of the box), but the non-bindability of rvalues to ref params and the associated dispute is veeery old, nothing new, so I don't agree that the language gets worse every day. ;)
Re: A simplification of the RvalueRef idiom
or I have simple class class View { this(Rectangle frame) {...} this(float, float, float, float) { ... } this(Point, Size) { ... } } then struct Point, Size and Rectangle (Point, Size) now I need to write 2 overloads for View class taking 4 floats or (Point, Size) and this must do in every descendant of View class.
Re: A simplification of the RvalueRef idiom
On Tuesday, 22 November 2016 at 16:57:28 UTC, kink wrote: I hate this 'idiom' too (just a clumsy workaround for something that should work out of the box), but the non-bindability of rvalues to ref params and the associated dispute is veeery old, nothing new, so I don't agree that the language gets worse every day. ;) d-idioms doesn't always paint a rosy picture of D, that's true. It's about "what can we do now with D, whatever it takes". It turns out almost everything can be done, but some things are worse than in other languages of course. The baby is too cute to throw with the bathwater ;)
Re: implementing --version?
Thanks! These tips are exactly what i needed :)
Re: Complex numbers are harder to use than in C
On Sunday, 20 November 2016 at 12:08:23 UTC, Ilya Yaroshenko wrote: You can use builtin complex numbers (cfloat/cdouble/creal). The idea of std.complex is wrong . Mir GLAS uses builtin complex numbers and I don't think they will be really deprecated. --Ilya Good to know! The builtin syntax is more reasonable than std.complex.
Re: Complex numbers are harder to use than in C
On Sunday, 20 November 2016 at 11:46:04 UTC, Marc Schütz wrote: Try placing it outside the function. Method call syntax doesn't work with nested functions, see here: https://dlang.org/spec/function.html#pseudo-member "The reason why local symbols are not considered by UFCS, is to avoid unexpected name conflicts." Aha! Now it works. Thank you for the explanation.
Re: A simplification of the RvalueRef idiom
On 11/22/2016 08:05 AM, Satoshi wrote: > Sorry, but D seems to be worse and worse day by day. I don't have extensive experience with other languages. In fact, the only other languages that I can claim proficiency are C and C++. (I also know Python just enough to find it incredible how it's used in the industry. Let's not get in to that discussion but I really tried and failed... in industry... :) ) Given that experience, I still find D a very useful tool. > This should be resolved by language and not doing it by template function. byRef() is not implicit due to a deliberae design decision. Walter talks about why the language lacks ref variables in his recent talk. No, I was not there and the audio is lost, so all we have at this point are the slides. It's the "Memory Safety and the D Programming Languge" presentation http://www.walterbright.com/ Slide 26 starts talking about ref and why it's only for parameters and returns. > Same thing should be applied for maybe monad and tuples. > > e.g. When I want to create simple function for drawing > > void lineTo(auto ref Point point...) { > //... > } > > It's easier to call it like: > Point p = Point(42, 42); > > lineTo(p); > lineTo(42, 42); Agreed but it opens the door for bugs. Assuming struct A { int a; } struct B { int b; int c; } void foo(int, int, int); If foo(1, 2, 3) meant foo(A(1), B(2, 3)) today, it could silently mean foo(A(1, 2), B(3)) if one moved one member from one struct to the other. Then there are other corner cases: writeln(1, 2, 3); Should that print the integers or A(1) and B(2, 3)? It's always better to be explicit. > lineTo(Point(42, 42)); // this > lineTo(Point(42, 42).byRef); // and this is just overhead I don't agree with those two examples but e.g. I find the following cumbersome: A[] arr = [ A(1), A(2) ]; > Sorry, but I want to write fast and safe programs in the fastest > possible way I think in these examples 'fast' and 'safe' don't work together. > and writing Point(...) or Point(...).byRef every time is > redundant overhead. > > Like http://pix.toile-libre.org/upload/original/1479816672.png > > > PS: sorry for sarcasm > - Satoshi > Agreed but I find solutions like the following acceptable. Yes, function names must be different but it's usually fine. import std.stdio; struct Point { int x; int y; } struct GraphicsContext { static GraphicsContext current() { return GraphicsContext(); } void moveTo(Point point) { writefln("Moving to %s", point); } void lineTo(Point point) { writefln("Drawing line to %s", point); } } void goTo(GraphicsContext gc, int x, int y) { gc.moveTo(Point(x, y)); } void drawTo(GraphicsContext gc, int x, int y) { gc.lineTo(Point(x, y)); } void main() { auto gc = GraphicsContext.current; gc.goTo(70, 70);// <-- Clean syntax gc.drawTo(70, 170); } Ali