Re: exclude current directory from search path in dmd ?
https://github.com/D-Programming-Language/dmd/pull/4823 On Sun, Jul 19, 2015 at 10:42 PM, ZombineDev via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: On Monday, 20 July 2015 at 03:33:08 UTC, Timothee Cour wrote: I've attached a reduced use case showing that the solutions proposed in this thread do not work, and wrote a local modification to dmd to allow a flag -exclude_cwd_from_imports that does work. Would that be acceptable to have this in official dmd? The best way to find out is to make a Pull Request. If it's hard to workaround than it's a good candidate for enhancement.
Re: monitoring variable evaluation time
On Monday, 20 July 2015 at 08:53:52 UTC, Clayton wrote: What could be the best-tool for monitoring the evaluation time of a variable . What I usually do is run the command :- - dmd -J. program.d Then I inspect the program.o file using vi for presence of compile-time constants and enums. I am wondering if this is the right way to do this. Am a bit skeptical about this as am working on pushing everything that the compiler can do to the compiler for faster run-time. I'm not sure that's what you want to know, but... The evaluation time of expressions is completely deterministic. Global (module level) or static variables, default values for struct/class members, template arguments, as well as enums, are evaluated at compile-time and thus their construction has no runtime costs. Everything else can, and usually does, happen at runtime (modulo anything I might have overlooked in the list above). But even then, compilers are free to evaluate things during optimization, as long as it's possible and makes no observable difference in behaviour. For example, with optimization enabled, both GDC and LDC can even evaluate some complex recursive function calls to their result. But these optimizations are optional. If you want a guarantee, you need to use one of the above contexts. You can use a simple helper template for that (untested): template forceCTFE(Args...) if(Args.length == 1) { alias forceCTFE = Args[0]; } void main() { auto myvar = forceCTFE!(foo(23)); }
monitoring variable evaluation time
What could be the best-tool for monitoring the evaluation time of a variable . What I usually do is run the command :- - dmd -J. program.d Then I inspect the program.o file using vi for presence of compile-time constants and enums. I am wondering if this is the right way to do this. Am a bit skeptical about this as am working on pushing everything that the compiler can do to the compiler for faster run-time.
Re: static opCall not working?
On Sunday, 19 July 2015 at 13:25:41 UTC, Ali Çehreli wrote: On 07/19/2015 03:26 AM, TC wrote: I tested the code from: http://dlang.org/struct.html Section: Dynamic Initialization of Structs struct S { int a; static S opCall(int v) { S s; s.a = v; return s; } static S opCall(S v) { S s; s.a = v.a + 1; return s; } } S s = 3; // sets s.a to 3 S t = s; // sets t.a to 3, S.opCall(s) is not called which does not compile (Error: cannot implicitly convert expression (3) of type int to S). What is wrong here? Docs or behavior? Tested it on asm.dlang.org where it fails with all compiler versions. The docs are not clear: s and t are not meant to be module-scope variables, which should be initialized in a 'static this()' (or 'shared static this()'). Put them inside a function like main() and it works fine. I think that's not what the OP means. The documentation is indeed saying that a struct with static opCall() can be used to _construct_ the structure, with exactly this syntax, i.e. not with `S a = S(3);`, but with `S a = 3;`. I, too, find this very surprising. opCall() is not a constructor...
Re: static opCall not working?
On Sunday, 19 July 2015 at 10:26:04 UTC, TC wrote: What is wrong here? Docs or behavior? Tested it on asm.dlang.org where it fails with all compiler versions. Docs are wrong here. `static opCall` was never intended to be used as constructor and I consider it a bad style in general. This is simply a workaround that people unhappy with lack of default struct constructor used but language actively resists such misusage (`auto s = new S(42)` won't work too btw) and it only causes confusion.
Re: monitoring variable evaluation time
On Monday, 20 July 2015 at 08:53:52 UTC, Clayton wrote: What could be the best-tool for monitoring the evaluation time of a variable . What I usually do is run the command :- - dmd -J. program.d Then I inspect the program.o file using vi for presence of compile-time constants and enums. I am wondering if this is the right way to do this. Am a bit skeptical about this as am working on pushing everything that the compiler can do to the compiler for faster run-time. You mean you want to know if some value is pre-computed during compilation? There are various places where the compiler is required to compute at compile time: * initializers of module level variables * initializers of static variables * enum values * dimensions of static arrays * template value arguments * probably a couple more I can't of right now In these places where pre-computation is guaranteed, it's called CTFE. Compilers are free to pre-compute other constants (constant folding). It's pretty safe to assume that simple, constant arithmetic expressions are evaluated at compile-time, maybe it's even guaranteed. Beyond that, things vary between compilers. Instead of checking if the compiler recognizes your constants and pre-computes them, I'd suggest to force it by using a CTFE context. To force CTFE in an otherwise non-CTFE context, you can use a little helper: enum ctEval(alias expr) = expr; void main() { auto x = ctEval!(/* some complex expression that would possibly not be constant folded otherwise */); } I'm not sure if this the best way to define ctEval. I thought it had found its way into phobos by now, but I can't find it anywhere. This very simple version here may have issues.
Re: What is the std.stream replacement?
On Monday, 20 July 2015 at 00:58:20 UTC, Charles Hixson wrote: I have DMD64 D Compiler v2.067.1 installed, and in the documentation of phobos what it says about std.stream is don't use it on new code. It doesn't, however, appear to offer any replacement. Certainly std.file, std.stdio, and std.path aren't replacements. So what *is* the appropriate replacement? More specificly, what should one use for binary i/o, particularly random access binary i/o? With fixed block size. There's none :( You can use std.stdio.File but it's not as flexible. This note in the documentation was there 3 years ago, and there's no replacement on the horizon, except some work in progress by Steven Schveighoffer (https://github.com/schveiguy/phobos/tree/new-io3)
Re: monitoring variable evaluation time
On Monday, 20 July 2015 at 09:29:26 UTC, anonymous wrote: On Monday, 20 July 2015 at 08:53:52 UTC, Clayton wrote: [...] You mean you want to know if some value is pre-computed during compilation? [...] Thankyou a lot for the suggestion. Am noting as I learn the language.
Re: monitoring variable evaluation time
On Monday, 20 July 2015 at 10:11:10 UTC, Marc Schütz wrote: On Monday, 20 July 2015 at 08:53:52 UTC, Clayton wrote: [...] I'm not sure that's what you want to know, but... The evaluation time of expressions is completely deterministic. Global (module level) or static variables, default values for struct/class members, template arguments, as well as enums, are evaluated at compile-time and thus their construction has no runtime costs. [...] Thankyou a lot for the suggestion. Am noting as I learn the language.
OPTLINK checkpoint(256)
I was still using 2.066.1. When I try to build using 2.067.0 or 2.067.1 I get: Linking... checkpoint(256) --- errorlevel 1 with an Unexpected OPTLINK Termination popup which lists a bunch of registers. I'm not sure how to proceed..
Re: OPTLINK checkpoint(256)
On Monday, 20 July 2015 at 13:16:43 UTC, Lemonfiend wrote: I was still using 2.066.1. When I try to build using 2.067.0 or 2.067.1 I get: Linking... checkpoint(256) --- errorlevel 1 with an Unexpected OPTLINK Termination popup which lists a bunch of registers. I'm not sure how to proceed.. First, try this: https://github.com/CyberShadow/DustMite/wiki It will minimize your code to isolate the problem.
std.algorithm each documentation terse
I have found the documentation for each in std.algorithm a bit terse. It seemed like it was an eager version of map, but it seems to be a bit more limited than that. In particular, the documentation says that if you can mutate the value in place, then you can call each on it. The first thing I noticed is that this works easiest (beyond in place operators) when you're using a void function and taking the input you want to change as ref. This is what I did in the foo and bar functions below. However, it's not the same thing as just applying the function. In the baz function, I mutate the value and then return a different value. Using baz with each doesn't change the value by 2, only by 1. What really confused me is that I can't use a lambda with each in a similar way as map. I think this is because the lambdas I'm using really aren't void functions. The part after the = is basically a return statement, so I'm not really mutating anything in place. Is there any way to do this with lambdas or are void functions required? Is there a way to write a void lambda that would work with each? import std.range : iota; import std.algorithm : each; import std.array : array; void foo(ref int x) { x += 1; } void bar(ref int x) { x *= x; } int baz(ref int x) { x += 1; return x + 1; } void main() { auto x = iota(3).array; x.each!((ref a) = a++); assert(x == [1, 2, 3]); //What you would expect x.each!((ref a) = foo(a)); assert(x == [2, 3, 4]); //What you would expect x.each!((ref a) = bar(a)); assert(x == [4, 9, 16]); //What you would expect x.each!((ref a) = baz(a)); assert(x == [5, 10, 17]); //What I would expect after thinking about it for a while x.each!((ref a) = a + 1); assert(x == [5, 10, 17]); //Not what I would expect x.each!((ref a) = a * a); assert(x == [5, 10, 17]); //Not what I would expect }
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: I have found the documentation for each in std.algorithm a bit terse. It seemed like it was an eager version of map, but it seems to be a bit more limited than that. In particular, the documentation says that if you can mutate the value in place, then you can call each on it. The first thing I noticed is that this works easiest (beyond in place operators) when you're using a void function and taking the input you want to change as ref. This is what I did in the foo and bar functions below. However, it's not the same thing as just applying the function. In the baz function, I mutate the value and then return a different value. Using baz with each doesn't change the value by 2, only by 1. What really confused me is that I can't use a lambda with each in a similar way as map. I think this is because the lambdas I'm using really aren't void functions. The part after the = is basically a return statement, so I'm not really mutating anything in place. Is there any way to do this with lambdas or are void functions required? Is there a way to write a void lambda that would work with each? import std.range : iota; import std.algorithm : each; import std.array : array; void foo(ref int x) { x += 1; } void bar(ref int x) { x *= x; } int baz(ref int x) { x += 1; return x + 1; } void main() { auto x = iota(3).array; x.each!((ref a) = a++); assert(x == [1, 2, 3]); //What you would expect x.each!((ref a) = foo(a)); assert(x == [2, 3, 4]); //What you would expect x.each!((ref a) = bar(a)); assert(x == [4, 9, 16]); //What you would expect x.each!((ref a) = baz(a)); assert(x == [5, 10, 17]); //What I would expect after thinking about it for a while x.each!((ref a) = a + 1); assert(x == [5, 10, 17]); //Not what I would expect x.each!((ref a) = a * a); assert(x == [5, 10, 17]); //Not what I would expect } Everything is exactly as I would expect. Lambdas with = are just shorthand that skips the return expression and std.algorithm.each just calls the lambda for each element in x, it doesn't say anything about copying the result back in to x. x.map!(a = a * a).copy(x);
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: Is there a way to write a void lambda that would work with each? Ugh, I hate that I can't edit posts. I meant to delete this line.
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 15:08:16 UTC, Nicholas Wilson wrote: But the lambda takes a ref parameter... Yes, but it never writes to it: x.each!((ref a) = a + 1); Instead, this should work: x.each!((ref a) = a = a + 1); ... as a short-hand for: x.each!((ref a) { a = a + 1; });
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 15:12:28 UTC, Marc Schütz wrote: On Monday, 20 July 2015 at 15:08:16 UTC, Nicholas Wilson wrote: But the lambda takes a ref parameter... Yes, but it never writes to it: x.each!((ref a) = a + 1); Instead, this should work: x.each!((ref a) = a = a + 1); ... as a short-hand for: x.each!((ref a) { a = a + 1; }); This works! Thanks.
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: I have found the documentation for each in std.algorithm a bit terse. It seemed like it was an eager version of map, but it seems to be a bit more limited than that. In particular, the documentation says that if you can mutate the value in place, then you can call each on it. The first thing I noticed is that this works easiest (beyond in place operators) when you're using a void function and taking the input you want to change as ref. This is what I did in the foo and bar functions below. However, it's not the same thing as just applying the function. In the baz function, I mutate the value and then return a different value. Using baz with each doesn't change the value by 2, only by 1. What really confused me is that I can't use a lambda with each in a similar way as map. I think this is because the lambdas I'm using really aren't void functions. The part after the = is basically a return statement, so I'm not really mutating anything in place. Is there any way to do this with lambdas or are void functions required? a += 1 in D is an expression that first mutates a and then returns a. Therefore, you can write this lamda: (ref a) = a += 1 And it should work fine with `each`. The expanded version that this desugars to is: int function(ref int a) { return a += 1; } On the other hand, however, a + 1 is an expression that does not mutate a. It just returns the value of a with 1 added to it. Therefore, `(ref a) = a + 1` cannot work, as it does not actually modify a. The best way to think of it is as if the body of your lambda is being executed in a `foreach` loop. If you translate some of your examples, it should become obvious as to what the result is. x.each!((ref a) = a++) becomes foreach (ref a; x) { a++; } And, of course, the answer is x == [2, 3, 4].
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 14:59:21 UTC, John Colvin wrote: On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: [...] Everything is exactly as I would expect. Lambdas with = are just shorthand that skips the return expression and std.algorithm.each just calls the lambda for each element in x, it doesn't say anything about copying the result back in to x. x.map!(a = a * a).copy(x); But the lambda takes a ref parameter...
Re: std.algorithm each documentation terse
Also, map is lazy, but each isn't.
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: I have found the documentation for each in std.algorithm a bit terse. It seemed like it was an eager version of map, but it seems to be a bit more limited than that. Why are you trying to use `each` in place which belongs to `map`?
Re: std.algorithm each documentation terse
On Monday, 20 July 2015 at 21:24:37 UTC, sigod wrote: On Monday, 20 July 2015 at 14:40:59 UTC, jmh530 wrote: I have found the documentation for each in std.algorithm a bit terse. It seemed like it was an eager version of map, but it seems to be a bit more limited than that. Why are you trying to use `each` in place which belongs to `map`? More just out of my own curiosity of trying to understand how it worked.
Re: Replacement of std.stream
On Sunday, 19 July 2015 at 17:34:27 UTC, Charles Hixson wrote: The documentation of std.mmfile.MmFile makes it an unacceptable replacement for std.stream. I can't even tell if it's features are missing, or just unintelligible. It rather looks as if you need to have enough RAM to hold the entire file in memory at once, but I'm not even sure of that. Documentation improvements are certainly welcome. However, it is just a wrapper over the posix functionality for memory mapped files: https://en.wikipedia.org/wiki/Mmap No need to store the whole file into RAM, the OS will manage paging for you.
C bindings: typedef struct conflicts with method
i tried to automagically create bindings for librdkafka (https://github.com/edenhill/librdkafka) with dstep. now the code contains typedefs structs with the same name as methods: ``` typedef struct rd_kafka_metadata { int broker_cnt; /* Number of brokers in 'brokers' */ struct rd_kafka_metadata_broker *brokers; /* Brokers */ int topic_cnt; /* Number of topics in 'topics' */ struct rd_kafka_metadata_topic *topics;/* Topics */ int32_t orig_broker_id; /* Broker originating this metadata */ char *orig_broker_name; /* Name of originating broker */ } rd_kafka_metadata_t; rd_kafka_metadata (rd_kafka_t *rk, int all_topics, rd_kafka_topic_t *only_rkt, const struct rd_kafka_metadata **metadatap, int timeout_ms); ``` what the correct way to bind these?