Re: what's the point of function template declarations if they can't be defined?
On Wednesday, February 07, 2018 13:39:55 Timothee Cour via Digitalmars-d- learn wrote: > ``` > void fun_bad3(T)(T a); // declaration [1] > void fun_bad3(T)(T a){}; // definition [2] > void test(){ > fun_bad3(1); > } > ``` > Error: test_all.fun_bad3 called with argument types (int) matches both: > main.d(11): test_all.fun_bad3!int.fun_bad3(int a) > and: > main.d(12): test_all.fun_bad3!int.fun_bad3(int a) > > should [1] be allowed? It's useful with stuff like version(Ddoc). > compler doens't allow defining it afterwards in > [2] (unlike function definitions, and, well, modulo this regression > https://issues.dlang.org/show_bug.cgi?id=18393) It's been my understanding that it's always been illegal to provide a definition for a function that was declared previously unless it was declared in a .di file, in which case, you're not really both declaring and defining it, but the .d file is used when the module is compiled, and the .di file is used by other modules which use that module, so the declaration and definition are not seen by the same run of the compiler. - Jonathan M Davis
Re: free func "front" is not picked up as a candidate when doing range.front(...)
On Wednesday, February 07, 2018 20:17:54 aliak via Digitalmars-d-learn wrote: > On Wednesday, 7 February 2018 at 20:08:10 UTC, Paul Backus wrote: > > You can only call a function with UFCS syntax if the object > > you're calling it with does not have a member with the same > > name as the function. Both iota's `Result` type and > > `FilterResult` have properties named "front", so you can't call > > your front function on them using UFCS syntax. > > ahhh... bummer. > > Do you know if it is a limitation that is yet to be implemented > or one that will not (cannot?) be implemented and if so what the > reason is? It would be a disaster if free functions could override member functions. For starters, it would be impossible to call the member function if that were allowed, whereas you can always call a free function by not using UFCS. And in general, it's far more desirable to have member function functions override free functions, because then you can do stuff like have have a range override find if it can provide a more efficient implementation than std.algorithm.find. If you want to override what a member function is doing, then you need to wrap the object in a new type. - Jonathan M Davis
deprecation warning after upgrade
Hi All, In my generic code I now get this error, which requires manually finding all -a[] array ops, but that is another matter. $/src/druntime/import/core/internal/arrayop.d-mixin-57(57,20): Deprecation: integral promotion not done for -_param_1[pos], use '-transition=intpromote' switch or -cast(int)(_param_1[pos]) Is there a way to avoid this in generic code so I can still take advantage of array ops? E.g. this.vec[] = -this.vec[]; Or do I have to do some wrangling like this? this.vec = this.vec.map!(a => -cast(int)(a)).array.to!(T[]) ?? What would be a good idiomatic way to fix this deprecation issue? I do not want to use the flag but make my code better, not mask the issue. Thanks, Norm
Re: Performance of default and enum parameters
On Wednesday, 7 February 2018 at 23:18:53 UTC, H. S. Teoh wrote: [snip] Appreciate the detailed reply. I had tried to look at the assembly with that tool recently discussed in the announce thread, but there was so much extra stuff reported that I threw up my hands.
Re: Performance of default and enum parameters
On Wed, Feb 07, 2018 at 11:04:29PM +, jmh530 via Digitalmars-d-learn wrote: [...] > If check is not passed, I think it depends on how default function > arguments work. I could imagine that it works in two ways: 1) if you > call bar(x), then the compiler effectively re-writes it to bar(x, > true), which would mean that the if statement must run, 2) the > compiler creates functions int bar(int x) and int bar(int x, bool > check), where the first has the check optimized away and the second is > as normal, calling bar(x) means that the optimized one is called. Default arguments mean precisely that: if you don't specify that parameter, the compiler inserts the default argument for you. IOW: int bar(int x, bool check = true) { ... } bar(1); // rewritten as bar(1, true); > If check is known at compile-time, I would think that the compiler > could optimize away the if statement because it is known at > compile-time which part will be there or not. [...] Default arguments are a syntactic construct. They have little to do with what optimizations are done by the compiler. A function without default arguments can be optimized the same way as a function with default arguments. Whether or not something is optimized away is more dependent on the optimizer than on the syntax used to write the code. If you want to know for sure, check the assembly output, e.g., of ldc. The last time I checked, ldc is able to inline and optimize away even nested loops (up to a certain complexity), needless to say a simple boolean if-statement like your example code. This was in the context of certain proposed Phobos optimizations, and it was funny because we were getting strange benchmark results like 0ms for the entire function when compiled with ldc. Disassembling showed that what actually happened was that ldc determined that since the return value of the function was never used, the entire function call could be deleted completely. In another case, because the function arguments were known at compile-time, ldc executed the function at compile-time and substituted the function call with just loading the return value directly into a register, so the function was never actually called. Basically, if you use a compiler with an aggressive optimizer like ldc's, don't waste your time with micro-optimizations. The compiler will do it for you. Trying to hand-optimize your code can sometimes backfire -- the code can become too strange for the optimizer to understand, so it gives up and ends up *not* optimizing it at all. In this day and age, the only time you actually need to hand-optimize is when a profiler has identified real hotspots, and usually the fix is relatively simple. (And IME, the real hotspots are often NOT where I predict them to be. So optimizing stuff before I have real data from a profiler is usually a waste of my time.) T -- Public parking: euphemism for paid parking. -- Flora
Performance of default and enum parameters
I'm a little curious on the impact of default and enum parameters on performance. In the simple example below, I have foo and bar that return different results depending on a bool. Foo is a template with check as a template parameter and bar is a normal function. foo creates two different versions so it never needs to perform a run-time evaluation of check. However, I was a little curious about bar. Obviously if check is passed as either true or false, then the if statement has to be run, but I wasn't sure what happens if check is not passed or if check is known at compile-time. If check is not passed, I think it depends on how default function arguments work. I could imagine that it works in two ways: 1) if you call bar(x), then the compiler effectively re-writes it to bar(x, true), which would mean that the if statement must run, 2) the compiler creates functions int bar(int x) and int bar(int x, bool check), where the first has the check optimized away and the second is as normal, calling bar(x) means that the optimized one is called. If check is known at compile-time, I would think that the compiler could optimize away the if statement because it is known at compile-time which part will be there or not. int foo(bool check = true)(int x) { static if (check) return x; else return x + 1; } int bar(int x, bool check = true) { if (check) return x; else return x + 1; } enum bool val = false; void main() { import std.stdio : writeln; int x = 1; writeln(foo(x));//two versions of foo writeln(foo!false(x)); //two versions of foo writeln(bar(x));//does run-time if happen? writeln(bar(x, true)); //if statement at run-time writeln(bar(x, false)); //if statement at run-time writeln(foo!val(x));//same as foo!false writeln(bar(x, val)); //does run-time if happen? }
Deep
Hi. I have been using D for more than 15 years now. But since I haven't done anything Note Worthy, I'll just post here in the newbie pen, even though I think my message is important. I just watched an episode of Computerphile about Type Theory. I wish, that Andrei would take a look at it. D seems to be a language that can cover all the levels of abstraction that C++ does, and then some. (1) D also covers the entire gamut of elementary to "deep shit" just smoothly without discontinuities, which makes it pretty unique. (That is, IMHO Lisp has a problem with the lower end of abstraction -- from a Real World Computing point of view.) https://www.youtube.com/watch?v=qT8NyyRgLDQ Combining the practical strength and abstraction power of D with this new paradigm, simply begs a visit from the likes of Andrei. (And of course all other heavy weight hitters!) Thank you for your time (1): The lowest possible level being assembly language, and the highest being something we have yet to develop. (Not invent, because this is a step-by-step process. But it is painfully obvious that D reaches way higher than C++ in this regard already.) D exceeds C++ at the upper end. Above that we find Lisp. I wouldn't call it a tie between D and Lisp, but they are close. Now, embracing Type Theory in a natural way, could give D a /practical/ advantage, if not a /theoretical/ one over Lisp. And that was the idea with this post. We need to set our ambitions high, just like Elon Musk does.
Re: Shouldn't D be added to this list?
On Tuesday, 6 February 2018 at 22:36:09 UTC, WhatMeWorry wrote: https://www.khronos.org/opengl/wiki/Language_bindings I was thinking that with derelictGL, D should be on this list? If so, I'm not sure how one would go about this? It is a wiki, anybody can add it, me thinks.
what's the point of function template declarations if they can't be defined?
``` void fun_bad3(T)(T a); // declaration [1] void fun_bad3(T)(T a){}; // definition [2] void test(){ fun_bad3(1); } ``` Error: test_all.fun_bad3 called with argument types (int) matches both: main.d(11): test_all.fun_bad3!int.fun_bad3(int a) and: main.d(12): test_all.fun_bad3!int.fun_bad3(int a) should [1] be allowed? compler doens't allow defining it afterwards in [2] (unlike function definitions, and, well, modulo this regression https://issues.dlang.org/show_bug.cgi?id=18393)
Re: Vibe.d rest & web service?
On Wednesday, 7 February 2018 at 19:50:31 UTC, Jacob Carlborg wrote: Have you tried this? No. But apart from the fact that I forgot to make the class inherit from an interface to that the rest interface would actually compile, the web interface is routed before the rest interface and so the rest interface would never be reached since the methods are all the same and the REST's are shadowed by the web's .
Re: Run-time initialised static variables
On Wednesday, 7 February 2018 at 20:10:10 UTC, dekevin wrote: On Wednesday, 7 February 2018 at 16:26:16 UTC, Dominikus Dittes Scherkl wrote: On Wednesday, 7 February 2018 at 12:10:38 UTC, dekevin wrote: struct ℚ{ ℤ num, den; //cannot call constructors on these, since they require gmp_init, which requires runtime code //Default initialiser disabled, since else num=0,den=0 You can use a different default initializer: ℤ num = 0, den = 1; Thus avoiding the bad denominator. I appreciate the help, but I cannot instantiate these variables with a constructor. Whenever I do, the compiler tries to figure out its values at compile-time. This it cannot do however, since the code requires gmp_init for constructing an explicit value, which is only available after dynamically linking GMP. Here is the error I get: source/gmp/z.d(117): Error: __gmpz_init_set_si cannot be interpreted at compile time, because it has no available source code source/util.d(575):called from here: _MpZ(__mpz_struct(0, 0, null)).this(0) source/gmp/z.d(117): Error: __gmpz_init_set_si cannot be interpreted at compile time, because it has no available source code source/util.d(575):called from here: _MpZ(__mpz_struct(0, 0, null)).this(1) I don't really know what to do now, since I have another struct which already uses static variables with the same naming convention and I'll also need it a second time when I write the bindings to MPFR. I should perhaps add how ℤ looks like. Here is a stripped-down version: struct ℤ { @disable this(); this(T)(T value) @trusted if (isArithmetic!T) { version(ccc) { ++_ccc; } static if (isUnsigned!T) __gmpz_init_set_ui(_ptr, value); else static if (isFloating!T) __gmpz_init_set_d(_ptr, value); else// isSigned integral __gmpz_init_set_si(_ptr, value); } ~this() @trusted { assert(_ptr, "Pointer is null"); //if(hasBeenInit) __gmpz_clear(_ptr); version(ccc) { ++_ccc; } } inout(__mpz_struct)* _ptr() inout return @system { return &_z; } }
Re: free func "front" is not picked up as a candidate when doing range.front(...)
On Wednesday, 7 February 2018 at 20:08:10 UTC, Paul Backus wrote: You can only call a function with UFCS syntax if the object you're calling it with does not have a member with the same name as the function. Both iota's `Result` type and `FilterResult` have properties named "front", so you can't call your front function on them using UFCS syntax. ahhh... bummer. Do you know if it is a limitation that is yet to be implemented or one that will not (cannot?) be implemented and if so what the reason is?
Re: Run-time initialised static variables
On Wednesday, 7 February 2018 at 16:26:16 UTC, Dominikus Dittes Scherkl wrote: On Wednesday, 7 February 2018 at 12:10:38 UTC, dekevin wrote: struct ℚ{ ℤ num, den; //cannot call constructors on these, since they require gmp_init, which requires runtime code //Default initialiser disabled, since else num=0,den=0 You can use a different default initializer: ℤ num = 0, den = 1; Thus avoiding the bad denominator. I appreciate the help, but I cannot instantiate these variables with a constructor. Whenever I do, the compiler tries to figure out its values at compile-time. This it cannot do however, since the code requires gmp_init for constructing an explicit value, which is only available after dynamically linking GMP. Here is the error I get: source/gmp/z.d(117): Error: __gmpz_init_set_si cannot be interpreted at compile time, because it has no available source code source/util.d(575):called from here: _MpZ(__mpz_struct(0, 0, null)).this(0) source/gmp/z.d(117): Error: __gmpz_init_set_si cannot be interpreted at compile time, because it has no available source code source/util.d(575):called from here: _MpZ(__mpz_struct(0, 0, null)).this(1) I don't really know what to do now, since I have another struct which already uses static variables with the same naming convention and I'll also need it a second time when I write the bindings to MPFR.
Re: free func "front" is not picked up as a candidate when doing range.front(...)
On Wednesday, 7 February 2018 at 19:25:01 UTC, aliak wrote: import std.range: iota; 0.iota.front(100).writeln; // Error: inout method std.range.iota!(int, int).iota.Result.front is not callable using a mutable object import std.algorithm: filter; auto arr = [0, 1]; arr.filter!"true".front(99).writeln; // Error: function std.algorithm.iteration.FilterResult!(unaryFun, int[]).FilterResult.front () is not callable using argument types (int) You can only call a function with UFCS syntax if the object you're calling it with does not have a member with the same name as the function. Both iota's `Result` type and `FilterResult` have properties named "front", so you can't call your front function on them using UFCS syntax.
Re: macOS preview D files
On 2018-02-07 20:28, Joel wrote: On Wednesday, 7 February 2018 at 12:45:43 UTC, Jacob Carlborg wrote: On 2018-02-07 02:24, Joel wrote: Using finder, I want to see D files shown in the preview column, I some times have with TextMate. Also on my iPhone (in iCloud app, open as a text file) would be a bonus too. D is not recognized correctly by TextMate, I'm working on fixing that. Cool. I'm not sure if Find is using the same functionality as QuickLook, but if it does, I have a pull request waiting for review for that. https://github.com/textmate/textmate/pull/1403 -- /Jacob Carlborg
Re: Vibe.d rest & web service?
On 2018-02-07 18:04, Nicholas Wilson wrote: Is it possible to have some urls routed to serve content and some to receive JSON in the same class? Basically I want: shared static this() { auto router = new URLRouter; auto a = new MyInterface; router.registerWebInterface(new MyInterface); //?? selective combination router.registerRestInterface(new MyInterface); //?? auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1","127.0.0.1"]; listenHTTP(settings, router); } class MyInterface { SomeData[] items; // Get void index() { render!("index.dt"); } // Get void getPage() { render!("page.dt", items); } // REST -> receive d as JSON. void postGiveMeData(SomeData d) { synchronized { items ~= d; } } } Have you tried this? -- /Jacob Carlborg
Re: macOS preview D files
On Wednesday, 7 February 2018 at 12:45:43 UTC, Jacob Carlborg wrote: On 2018-02-07 02:24, Joel wrote: Using finder, I want to see D files shown in the preview column, I some times have with TextMate. Also on my iPhone (in iCloud app, open as a text file) would be a bonus too. D is not recognized correctly by TextMate, I'm working on fixing that. Cool.
free func "front" is not picked up as a candidate when doing range.front(...)
Hi, I'm trying to make a range.front free function that can be given a defaultValue. Doesn't seem to be working as is written below, seems like the compiler doesn't see the free function as a viable candidate. Isn't it supposed to do its UFCS wizardry and pick up the free func? import std.stdio; auto front(Range, T)(Range range, T defaultValue) { import std.range: empty, front; return range.empty ? defaultValue : range.front; } void main() { import std.range: iota; 0.iota.front(100).writeln; // Error: inout method std.range.iota!(int, int).iota.Result.front is not callable using a mutable object import std.algorithm: filter; auto arr = [0, 1]; arr.filter!"true".front(99).writeln; // Error: function std.algorithm.iteration.FilterResult!(unaryFun, int[]).FilterResult.front () is not callable using argument types (int) arr.front(30).writeln; // OK import std.range: front; arr.front(30).writeln; // Error: template std.range.primitives.front cannot deduce function from argument types !()(int[], int), candidates are: std.range.primitives.front(T)(T[] a) ... } Cheers
Re: Vibe.d rest & web service?
On Wednesday, 7 February 2018 at 18:38:15 UTC, Seb wrote: How about using the normal Vibe.d Web Service? Stupid question: whats the difference? An example from my WIP project vibe-by-example project: https://github.com/wilzbach/vibe-d-by-example/blob/master/web/service.d I also have a fork of vibe.web.web that adds additional convenience features to Vibe.d: https://github.com/teamhackback/hb-web (I have been struggling to get most of them merged upstream - https://github.com/vibe-d/vibe.d/pulls/wilzbach)
Re: Vibe.d rest & web service?
On 2/7/18 12:04 PM, Nicholas Wilson wrote: Is it possible to have some urls routed to serve content and some to receive JSON in the same class? Basically I want: shared static this() { auto router = new URLRouter; auto a = new MyInterface; router.registerWebInterface(new MyInterface); //?? selective combination router.registerRestInterface(new MyInterface); //?? auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1","127.0.0.1"]; listenHTTP(settings, router); } class MyInterface { SomeData[] items; // Get void index() { render!("index.dt"); } // Get void getPage() { render!("page.dt", items); } // REST -> receive d as JSON. void postGiveMeData(SomeData d) { synchronized { items ~= d; } } } Yes you can, but it's not pretty. interface MyInterface { void postGiveMeData(SomeData d); } class MyInterfaceImpl : MyInterface { void postGiveMeData(SomeData d) { ... } void getPage() { ... } void index() { ... } } auto myI = new MyInterfaceImpl; router.registerRestInterface(myI); router.get("/route/to/getPage", &myI.getPage); router.get("/route/to/index", &myI.index); This worked for me, but note that my "non-rest" function was static, so I didn't need to worry about instances. I'm not sure if the above works exactly right for you. However, I would recommend actually not doing this for your purpose. My case was different -- I still wanted routes that were REST routes, but I wanted to control the result streaming (the vibe.d return value doesn't work with ranges, so I would have had to construct essentially my entire database in an array so I could return it). In your case, I think you are better off using 2 classes, and one shared data storage area. -Steve
Re: Vibe.d rest & web service?
On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson wrote: Is it possible to have some urls routed to serve content and some to receive JSON in the same class? Basically I want: shared static this() { auto router = new URLRouter; auto a = new MyInterface; router.registerWebInterface(new MyInterface); //?? selective combination router.registerRestInterface(new MyInterface); //?? auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1","127.0.0.1"]; listenHTTP(settings, router); } class MyInterface { SomeData[] items; // Get void index() { render!("index.dt"); } // Get void getPage() { render!("page.dt", items); } // REST -> receive d as JSON. void postGiveMeData(SomeData d) { synchronized { items ~= d; } } } How about using the normal Vibe.d Web Service? An example from my WIP project vibe-by-example project: https://github.com/wilzbach/vibe-d-by-example/blob/master/web/service.d I also have a fork of vibe.web.web that adds additional convenience features to Vibe.d: https://github.com/teamhackback/hb-web (I have been struggling to get most of them merged upstream - https://github.com/vibe-d/vibe.d/pulls/wilzbach)
Re: Vibe.d rest & web service?
On Wednesday, 7 February 2018 at 17:57:09 UTC, Jesse Phillips wrote: On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson wrote: Is it possible to have some urls routed to serve content and some to receive JSON in the same class? This seems unlikely to me, the function signature doesn't provide a way to distinguish between REST and not. I'm also not sure it is necessary, you can certainly have multiple class which provide REST and Web endpoints. You can even dynamically build routes within a route. Hmm, this might be one of the few use cases for nested classes. But is would still require some routing trickery.
Re: Vibe.d rest & web service?
On Wednesday, 7 February 2018 at 17:04:13 UTC, Nicholas Wilson wrote: Is it possible to have some urls routed to serve content and some to receive JSON in the same class? This seems unlikely to me, the function signature doesn't provide a way to distinguish between REST and not. I'm also not sure it is necessary, you can certainly have multiple class which provide REST and Web endpoints. You can even dynamically build routes within a route.
Vibe.d rest & web service?
Is it possible to have some urls routed to serve content and some to receive JSON in the same class? Basically I want: shared static this() { auto router = new URLRouter; auto a = new MyInterface; router.registerWebInterface(new MyInterface); //?? selective combination router.registerRestInterface(new MyInterface); //?? auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1","127.0.0.1"]; listenHTTP(settings, router); } class MyInterface { SomeData[] items; // Get void index() { render!("index.dt"); } // Get void getPage() { render!("page.dt", items); } // REST -> receive d as JSON. void postGiveMeData(SomeData d) { synchronized { items ~= d; } } }
Re: Run-time initialised static variables
On Wednesday, 7 February 2018 at 12:10:38 UTC, dekevin wrote: struct ℚ{ ℤ num, den; //cannot call constructors on these, since they require gmp_init, which requires runtime code //Default initialiser disabled, since else num=0,den=0 You can use a different default initializer: ℤ num = 0, den = 1; Thus avoiding the bad denominator.
Re: extern(C++) in win32.mak
On Wednesday, 7 February 2018 at 14:38:37 UTC, Jacob Carlborg wrote: On 2018-02-07 14:47, Paul D Anderson wrote: I get Error: 'of..\generated\windows\release\32\lexer.lib' not found I don't think this file is built anymore. It's a leftover of the lexer experiment and AFAICT still built: https://github.com/dlang/dmd/blob/master/src/win32.mak#L317 https://github.com/dlang/dmd/blob/master/src/win32.mak#L336 It looks to me as if at ' -of$@ ', the '-of' flag is supposed to specify the output file, but is being interpreted as part of the filename. Yeah looks like it. What HOST_DC do you use (i.e. what DMD version)? As mentioned, this file is built by various CIs, so it's pretty interesting to see that it doesn't work for you.
Re: more OO way to do hex string to bytes conversion
On Wednesday, 7 February 2018 at 14:47:04 UTC, Ralph Doncaster wrote: p.s. the cast should probably be to immutable ubyte[]. I'm guessing without it, there is an automatic copy of the data being made. No copy - you just get undefined behavior if you actually try to modify it!
Re: more OO way to do hex string to bytes conversion
On Tuesday, 6 February 2018 at 18:33:02 UTC, Ralph Doncaster wrote: I've been reading std.conv and std.range, trying to figure out a high-level way of converting a hex string to bytes. The only way I've been able to do it is through pointer access: import std.stdio; import std.string; import std.conv; void main() { immutable char* hex = "deadbeef".toStringz; for (auto i=0; hex[i]; i += 2) writeln(to!byte(hex[i])); } While it works, I'm wondering if there is a more object-oriented way of doing it in D. After a bunch of searching, I came across hex string literals. They are mentioned but not documented as a literal. https://dlang.org/spec/lex.html#string_literals Combined with the toHexString function in std.digest, it is easy to convert between hex strings and byte arrays. import std.stdio; import std.digest; void main() { auto data = cast(ubyte[]) x"deadbeef"; writeln("data: 0x", toHexString(data)); } p.s. the cast should probably be to immutable ubyte[]. I'm guessing without it, there is an automatic copy of the data being made.
Re: extern(C++) in win32.mak
On 2018-02-07 14:47, Paul D Anderson wrote: I get Error: 'of..\generated\windows\release\32\lexer.lib' not found I don't think this file is built anymore. -- /Jacob Carlborg
Re: extern(C++) in win32.mak
On Wednesday, 7 February 2018 at 08:28:23 UTC, Seb wrote: On Wednesday, 7 February 2018 at 06:05:54 UTC, Paul D Anderson wrote: Is there anyone who knows the ins and outs of the makefile that can shed some light? Thanks, Paul I recommend cloning DMD directly from git if you want to compile from source. There are many CIs in place that ensure that it always works. I downloaded from git but still get an error, though it's no longer the ddoc file error. At this line (316-7), $G\lexer.lib: $(LEXER_SRCS) $(ROOT_SRCS) $(STRING_IMPORT_FILES) $G $(HOST_DC) -of$@ -vtls -lib -J$G $(DFLAGS) $(LEXER_SRCS) $(ROOT_SRCS) I get Error: 'of..\generated\windows\release\32\lexer.lib' not found It looks to me as if at ' -of$@ ', the '-of' flag is supposed to specify the output file, but is being interpreted as part of the filename. Does anyone know what the problem is? Paul
Re: extern(C++) in win32.mak
On Wednesday, 7 February 2018 at 06:18:04 UTC, rikki cattermole wrote: On 07/02/2018 6:05 AM, Paul D Anderson wrote: I don't understand the following line in dmd/src/win32.mak: extern (C++) __gshared const(char)* ddoc_default = import ("default_ddoc_theme.ddoc"); That is a string import (-J). What does the word "import" mean in this context? I can't find any documentation on the use of import in this way, and the line fails to compile during the make. https://dlang.org/spec/expression.html#import_expressions Thank you. I did not know that. The error was caused by an over-zealous virus checker preventing some dmc executables from downloading. Paul
Re: macOS preview D files
On 2018-02-07 02:24, Joel wrote: Using finder, I want to see D files shown in the preview column, I some times have with TextMate. Also on my iPhone (in iCloud app, open as a text file) would be a bonus too. D is not recognized correctly by TextMate, I'm working on fixing that. -- /Jacob Carlborg
Re: Run-time initialised static variables
On Wednesday, 7 February 2018 at 00:31:01 UTC, Jonathan M Davis wrote: On Tuesday, February 06, 2018 23:50:52 dekevin via Digitalmars-d-learn wrote: Thanks a lot! I will change all my initialisations to static constructors now. I should point out that the downside to static constructors is that if you have modules that recursively depend on each other, the program throws an Error at startup, because the runtime can't determine the correct order of initialization. So, while static constructors can be very useful, you do have to be careful with them. The only additional problem I have, is that ℚInf has a disabled default constructor. D does not have default constructors. What you're really disabling is default initialization. This is an important distinction in understanding how objects are initialized in D. The init value is known at compile time and can't involve runtime stuff, whereas a default constructor would be able to run arbitrary code at runtime. Is there a way to allow shared static constructors, but not the default constructor? struct ℚInf { ℚ qval; immutable static ℚInf zero; @disable this(); shared static this() { zero.qval = ℚ(0); } this(long num, long den) { qval = ℚ(num,den); //this initialisation requires dynamically linked code } } If you're initializing an immutable variable, you have to initialize it in one go. What you're doing is letting it be default initialized (which results in a compilation error, because default initialiaztion is disabled for that type) and then assigning to one of its members. If the default initialization weren't disabled, you'd get an error about not being able to mutate an immutable variable, whereas the fact that you disabled default initialization but did not explicitly initialize the variable results in a compilation error about not initializing the variable. If you want zero to be immutable, you must initialize the entire object at once. e.g. zero = QInf(0, 0); or whatever makes sense. If you need zero to be initialized differently from other QInfs, then you could make a private constructor that just takes the value for qval. But it either has to be default initialized with whatever the init type is (which you clearly don't want, since you disabled that), or it needs to be explicitly given a value. - Jonathan M Davis Ah I see the distinction between initialisation and construction now. Disabling default initialisation was necessary, because part of the code of the initialisation code of ℚ is linked at runtime (mainly to initialise ℤ, which relies on gmp_init which is linked at runtime). But even if I initialise it in one go, the compiler still complains and wants to initialise posinf (complains that default construction is disabled). I also tested it with a static constructor and a non-immutable type and that didn't work either. Here is a stripped down version of the important bits: struct ℚInf { ℚ qval; enum Inf { negInf=-1, nonInf=0, posInf=+1, } Inf inf; immutable static ℚInf posinf; //at this line the compiler complains that default construction is disabled for type immutable(ℚInf) @disable this(); shared static this() { posinf = ℚInf(Inf.posInf); //neginf = ℚInf(Inf.negInf); } private this(Inf inf) { assert(inf != nonInf); this.inf = inf; qval = ℚ(0,1); } this(long num, long den) { inf=Inf.nonInf; qval = ℚ(num,den); } } struct ℚ{ ℤ num, den; //cannot call constructors on these, since they require gmp_init, which requires runtime code //Default initialiser disabled, since else num=0,den=0 @disable this(); this(long num){ this(num.ℤ); } this(ℤ num){ this.num=ℤ(num); this.den = 1; } this(ℤ num,ℤ den){ assert(den != ℤ(0)); //Disable this for speed if(den<0){ num=-num; den=-den; } auto d=gcd(abs(num),den); num/=d, den/=d; this.num=num; this.den=den; } this(long num, long den) { this(ℤ(num),ℤ(den)); } }
Re: GUI program on Mac OS in D?
On Monday, 5 February 2018 at 19:44:37 UTC, Jacob Carlborg wrote: Note that this applies to all classes, not just NSString. Ah yes, I will make sure it works for all the NSObject types. class NSStringRef { public: this(string s) { str_ = NSString.alloc.initWithBytes(cast(immutable(ubyte)*) s.ptr, s.length, NSStringEncoding.NSUTF8StringEncoding); } ~this() { str_.release(); } Note that this is not deterministic. There's not even a guarantee that a destructor for a class will be run at all. Oh I simply tested this by running millions of allocations and it seemed to work but I will have to use a struct then instead I guess. NSStringRef s = new NSStringRef("Hello"); NSLog(s.str); You can add an "alias this" [1] to avoid calling "str" explicitly. Ah that's neat! Currently the only correct way would be to wrap the class in a struct. There as been some talk to extend the language to support for reference counted classes [2]. Ok that sounds good. However, I'm mostly interested in how to make it work with the tools that are available now :)
Re: extern(C++) in win32.mak
On Wednesday, 7 February 2018 at 06:05:54 UTC, Paul D Anderson wrote: I don't understand the following line in dmd/src/win32.mak: extern (C++) __gshared const(char)* ddoc_default = import ("default_ddoc_theme.ddoc"); What does the word "import" mean in this context? I can't find any documentation on the use of import in this way, and the line fails to compile during the make. The error message is: file "default_ddoc_theme.ddoc" cannot be found or not in a path specified with -J The file is in the directory dmd2/src/res, which is specified with -J../res in the build. Is there anyone who knows the ins and outs of the makefile that can shed some light? Thanks, Paul I recommend cloning DMD directly from git if you want to compile from source. There are many CIs in place that ensure that it always works.