Re: Compile time vs run time -- what is the difference?
On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear wrote: In Java and some other languages, during compile time the code gets executed into Java bytecode. This also happens for C#. I don't know if there is an equivalent 'intermediate' language for D that your code gets translated to. With statically compiled languages like D, C, and C++, the compiler ultimately translates your source code to what's referred to as "machine code". Compilers output object files, which are in turn linked into an executable file by a linker. Static compilers can use intermediate representations like Java bytecode. For example, compilation could consist of two steps handled by two different programs, one that translates the source to bytecode, and one that translates the bytecode to an object file. This is how LLVM-based compilers like Clang and LDC work. Clang translates C source to LLVM IR (Intermediate Representation). LDC translated C source to LLVM IR. Both pass the generated IR to the LLVM compiler, which outputs the object files that are then given to a linker. Static Java compilers do the same thing with Java bytecode. Java JIT compilers built into Java VMs translate Java bytecode to machine code while the program is running. So compilation is just the act of translating from one source format to another (e.g., raw source code to machine code, or raw source code to bytecode, or bytecode to machine code). In general, I have a very vague understanding of these concept.s I don't understand the basics of how compile time and run time works in D language, it wasn't really explained in the book so when I see terms like 'compile time' and 'run time' I only have a very vague idea of what these things mean and how the process works for D language when compared to other high level languages. Anything that happens at compile time means it happens while the compiler is translating the source. Anything that happens at run time happens while the compiled program is running. So take this example: ```d uint fourcc(char a, char b, char c, char d) { return (a << 0) | (b << 8) | (c << 16) | (d << 24); } // Here, fourcc is evaluated at compile time enum nv12 = fourcc('N', 'V', '1', '2'); void main() { writeln(nv12); // Here, fourcc is evaluated at runtime writeln(fourcc('Y', 'V', '1', '2')); } ``` When the compiler is processing this source code, it encounters the declaration of `nv12`. Since this is an `enum`, it's a compile-time constant that cannot be changed at run time. That means that any value used to initialize it must also be known at compile time. One way to do that would be to use a literal, but in this case it's initialized with a call to the `fourcc` function. So the compiler evaluates the fourcc function and uses the result as the initializer of `nv12`. In other words, the end result is just the same as if I had written `enum nv12 = 842094158`. The second call to `fourcc` in the main function is not in a compile-time context, so it does not happen at compile time. It happens at run time, i.e., when you double click the executable that the compiler and linker generated (or type its name on the command line). The general rule is: if a function call is in a context such that it *must* be evaluated at compile time, then the compiler will evaluate it. Otherwise, it's a normal run-time evaluation.
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 16:43:49 UTC, Ali Çehreli wrote: On 12/27/22 07:09, Sergei Nosov wrote: If what you are looking for is a way of defining a variable for "any InputRange that produces a specific type (size_t in this case)", then there is inputRangeObject, which uses OOP: https://dlang.org/phobos/std_range_interfaces.html#InputRange I have an additional example here: http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.inputRangeObject Ali Thanks, everyone! I guess, this answer is the closest to what I was looking for. Somehow, I missed the range interfaces (and was considering to use `Variant` or smth). It does seem to answer the original question, albeit with layer(s) of indirection. ``` auto indicies = iota(3); RandomAccessFinite!int ai = indexed(a, indicies).inputRangeObject; ai = indexed(ai, iota(2)).inputRangeObject; ``` Still, my gut feel is that some compile-time solution is possible - will, probably, tinker with it for a little more. Why not use filter(), isn't it important to filter out what's in range? That does something different. Well, pretty sure this isn't what you meant by "same variable" but since it technically does what you want, I decided to share it: Basically I'm abusing array and this thing might be pretty memory heavy... Yeah, using arrays is another alternative, but as you mention, it uses more memory and makes index evaluation eager (vs lazy).
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ``` auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); ai = indexed(ai, iota(2)); writeln(ai); ``` Basically, my idea is to apply `indexed` to an array several times and have all the intermediaries saved in the same variable. The provided code doesn't compile with an error: ``` Error: cannot implicitly convert expression `indexed(ai, iota(2))` of type `Indexed!(Indexed!(int[], Result), Result)` to `Indexed!(int[], Result)` ``` I wonder, if there's a way to "collapse" or "simplify" the `Indexed!(Indexed!(int[], Result), Result)` type to just `Indexed!(int[], Result)` ? Well, pretty sure this isn't what you meant by "same variable" but since it _technically_ does what you want, I decided to share it: Basically I'm abusing `array` and this thing might be pretty memory heavy... ```d import std; void main() { auto a = [3, 6, 2, 1, 5, 4, 0]; auto indices = iota(3); auto ai = indexed(a, indices).array; ai = indexed(ai, iota(2)).array; writeln(ai); // [3, 6] } ```
Re: Compile time vs run time -- what is the difference?
On 12/27/22 9:31 PM, thebluepandabear wrote: I am reading through the free book on learning D by Ali Çehreli and I am having difficulties understanding the difference between compile time execution and run time execution in D language. Compile time execution is running your code being compiled *while being compiled*. It allows you to generate compile-time data without having to write specialized "compile time only" constructs like templates or explicitly marked functions (as other languages typically do). Compile time data doesn't consume any runtime to execute, it's already done by the time your binary is running. It also is usable *at compile time*, for things like `static if`, or `mixin`. The intermediate language being executed is the parsed and semantically analyzed AST nodes. -Steve
Compile time vs run time -- what is the difference?
I am reading through the free book on learning D by Ali Çehreli and I am having difficulties understanding the difference between compile time execution and run time execution in D language. What I do understand is that compile time and run time are the two processes that your code goes through to be executed natively. Compile time is the first stage. During compile time, the compiler checks for basic syntax errors such as a missing semicolon, typos throughout the codebase. Then the run time stage begins. Other errors are only able to be spotted during run time such as exceptions, dividing by zero, assert blocks. In Java and some other languages, during compile time the code gets executed into Java bytecode. This also happens for C#. I don't know if there is an equivalent 'intermediate' language for D that your code gets translated to. In general, I have a very vague understanding of these concept.s I don't understand the basics of how compile time and run time works in D language, it wasn't really explained in the book so when I see terms like 'compile time' and 'run time' I only have a very vague idea of what these things mean and how the process works for D language when compared to other high level languages. Any help would be appreciated.
Re: Confusion about `Random`
On Sunday, 25 December 2022 at 14:47:49 UTC, Siarhei Siamashka wrote: Just in case if you are not joking, caching a certain amount of dice rolls to reuse them later in a circular fashion would make a bad quality pseudorandom number generator (a slightly upgraded version of the xkcd joke). Don't do this. Naturally. I was joking, and I was also describing the erroneous behavior of the parser of the language I was writing; which was to substitute/cache a randomly generated number into a concrete syntax tree when interpreted, instead of making actual calls to the RNG at runtime, which is the correct (now current) behavior. The joke was that I automated the manual dice-rolling part to arrive more efficiently at the incorrect solution.
Re: How to parse enum from a string ?
On Wednesday, 27 May 2020 at 17:33:33 UTC, Vinod K Chandran wrote: Hi all, Assume that i have an enum like this. enum TestEnum { Received = 1, Started , Finished , Sent } I am saving this enum values as string in database. So, when i retrieve them from the database, how can i parse the string into TestEnum ? In vb. net, i can use [Enum].Parse(GetType( TestEnum), "Started") How to do this in D ? Parsing enum from a string can be done using the Enum.Parse() method. First, the enum type is passed into the method as a parameter. Then, the string to be parsed is passed in as the second parameter. If the string cannot be parsed into the enum type, then a exception will be thrown. To avoid this, the TryParse() method can be used instead, which will return a boolean value. https://andersenlab.com/blueprint/choosing-the-best-test-automation-frameworks
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 16:40:31 UTC, Salih Dincer wrote: ```d import std.algorithm; import std.stdio; import std.range; int[] a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = a.filter!(e => e >= indicies.front && e <= indicies.back); ai.writeln; // [2, 1, 0] ``` Or? ```d indicies.each!((i) => a[i].write(" ")); writeln(); // 3 6 2 ``` SDB@79
Re: Can you simplify nested Indexed types?
On 12/27/22 07:09, Sergei Nosov wrote: > Basically, my idea is to apply `indexed` to an array several times and > have all the intermediaries saved in the same variable. There may be other ways of achieving the same goal without assigning to the same variable. > I wonder, if there's a way to "collapse" or "simplify" the > `Indexed!(Indexed!(int[], Result), Result)` type to just > `Indexed!(int[], Result)` ? If what you are looking for is a way of defining a variable for "any InputRange that produces a specific type (size_t in this case)", then there is inputRangeObject, which uses OOP: https://dlang.org/phobos/std_range_interfaces.html#InputRange I have an additional example here: http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.inputRangeObject Ali
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ```d auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); ai = indexed(ai, iota(2)); writeln(ai); ``` Why not use `filter()`, isn't it important to filter out what's in range? ```d import std.algorithm; import std.stdio; import std.range; int[] a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = a.filter!(e => e >= indicies.front && e <= indicies.back); ai.writeln; // [2, 1, 0] ``` SDB@79
Re: Can you simplify nested Indexed types?
On 12/27/22 10:31 AM, Sergei Nosov wrote: On Tuesday, 27 December 2022 at 15:20:24 UTC, Salih Dincer wrote: On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ```d auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); //ai = indexed(ai, iota(2)); writeln(ai); ``` I confuse about comment line that I mark... SDB@79 Not sure I'll be more helpful, but I'll try to add more details. I have an array and I use `indexed` on it. Conceptually, I now have a second array, but it doesn't exist in memory explicitly - only a function to map indicies from "second array" to "first array" is stored; all the values are stored once - in the "first array". Now, I want to have third array that will do the same trick with the second array. The problem is that the second array is not really an array (but, conceptually, it is an array with random access). If I create a new variable with `auto` as type - obviously, it works. But can I use the same variable I used to store the "second array"? (In the provided code that doesn't work because of the type mismatch). So the short answer is no. The long of it is that Indexed is using a source range to give it indexes. In order to save it as the same type, you need to resolve the source of the indexes, when indiexed with the new source range, into the same type, which is not something the library can do. It would have to be specialized to recognize it's using iota as the index range, and then transform the iotas into one iota call. Which isn't impossible, but would be something specialized to this problem. What could be an answer is to have a function that takes 2 iotas, and provides the values as if you were applying the indexes of one to the other, something like: ```d iota!T translate(T)(iota!T orig, iota!T mapping) { // you write this part } ``` Then you can possibly define a function that can convert it properly. -Steve
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 15:20:24 UTC, Salih Dincer wrote: On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ```d auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); //ai = indexed(ai, iota(2)); writeln(ai); ``` I confuse about comment line that I mark... SDB@79 Not sure I'll be more helpful, but I'll try to add more details. I have an array and I use `indexed` on it. Conceptually, I now have a second array, but it doesn't exist in memory explicitly - only a function to map indicies from "second array" to "first array" is stored; all the values are stored once - in the "first array". Now, I want to have third array that will do the same trick with the second array. The problem is that the second array is not really an array (but, conceptually, it is an array with random access). If I create a new variable with `auto` as type - obviously, it works. But can I use the same variable I used to store the "second array"? (In the provided code that doesn't work because of the type mismatch).
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ```d auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); //ai = indexed(ai, iota(2)); writeln(ai); ``` I confuse about comment line that I mark... SDB@79
Re: Pure D frontend as library.
On Tuesday, 27 December 2022 at 12:22:45 UTC, Johan wrote: does semantic analysis (create AST; note that there is a ton of calls needed to complete SeMa), and finally outputs object code. If you want to capitalize the word use SemA. ;)
Re: Pure D frontend as library.
On Monday, 26 December 2022 at 19:13:01 UTC, Alexandru Ermicioi wrote: Hi team, I'd like to ask a lazy question: How easy is to use D compiler frontend without backend? How complicated would be to write a transpiler, and from which files should you start modifications? I'm wondering if something like https://typescripttolua.github.io/ could be done, but with d as language. From my limited knowledge, I should have an AST visitor that transpiles to target language, and some entry point for application which configures D frontend to use my AST visitor to generate code. I've no idea from where to start. If you know some documentation or tutorials, that would be appreciated. You can have a look at LDC's code, which does what you are saying. LDC first initializes itself (`cppmain()`) and then calls `mars_mainBody` (https://github.com/ldc-developers/ldc/blob/e5c97c6468334c65130a654c8aec819c51dd61d3/dmd/mars.d#L197) which reads source code files, does semantic analysis (create AST; note that there is a ton of calls needed to complete SeMa), and finally outputs object code. I'd start by copying the initialization and SeMa parts and stopping before the codegen part, removing all things that you think you will not need. The difficult thing is interpreting the AST. LDC does not use a visitor, don't get stuck on that idea, you don't necessarily need it. Documentation of the AST is not great; to discover what things mean / what needs to be done, consult the handling of AST nodes by LDC or DMD's glue layers. Of course you don't have to implement everything at the start. Just get function definitions, function calls, and string definitions going first --> that's what your "hello world" needs ;) I have never looked at GDC's code, but I presume it is quite similar in this regard to LDC, so you can look at that too. -Johan
Re: Pure D frontend as library.
On 27/12/2022 9:34 PM, Alexandru Ermicioi wrote: Any idea from which file should I start at least learning about this glue code? You can look at dmd's... but realistically the work hasn't been done at that level to make it easy to work with. https://github.com/dlang/dmd/blob/master/compiler/src/dmd/glue.d https://github.com/dlang/dmd/blob/master/compiler/src/dmd/gluelayer.d Note how it doesn't let you use your own implementation. This is very much throwing you into the deep end without any help.
Re: Pure D frontend as library.
On Monday, 26 December 2022 at 23:08:59 UTC, Richard (Rikki) Andrew Cattermole wrote: ... That on the other hand... Yeah, things aren't great on that front. The thing you want to implement is what we call glue code and isn't really setup right now for this (nobody has tried like this, ignoring ldc/gdc as they modify it). Hi, thx for information. Any idea from which file should I start at least learning about this glue code? Also, since this is not yet done, is there a way to insert this custom glue code without modifying D frontend source code? If not which file should I register custom changes? Thanks, Alexandru.