Re: Rosetta Commatizing numbers
On Wednesday, 31 May 2017 at 15:44:51 UTC, Ivan Kazmenko wrote: So, two custom calls, two minor changes, no sweat. Is everything right now? Even if not: that was fast, we can do another iteration. When we have a short readable solution with no special cases, the first few changes are going to be easy. Ivan Kazmenko. I followed that advice, and found and fixed more bugs that were lurking in the original and in my complications. When the number begins with a decimal point, that's an edge case none of the earlier versions were handling right. I added a regression test for that. I just posted my latest version at Rosetta, without the unnecessary complications. I hope you like it better. http://rosettacode.org/wiki/Commatizing_numbers#D (The complications weren't totally useless though. Without trying the complications, I wouldn't have tested enough to make as much improvement as I have. Overcomplicated features are something to avoid releasing, except in a repo folder of extras for other programmers to try fiddling with, and Rosetta code isn't exactly that.)
Re: Rosetta Commatizing numbers
On Wednesday, 31 May 2017 at 15:44:51 UTC, Ivan Kazmenko wrote: On Wednesday, 31 May 2017 at 13:27:24 UTC, Solomon E wrote: Fine, by the numbers: 1. pi has the commas start at the wrong digit, and doesn't follow the explicit instructions to use spaces as the separator and a grouping of 5 Can be solved by calling the function with a right set of parameters: start = 6 and step = 5. That's what function parameters are for. Here, I understand that a real-world solution would try to center around the decimal point. There are, however, two reasons not to do so. First, it is not required in the problem statement. Second, the solutions in other languages don't interpret the statement like that, and instead, just add a parameter to start reading from a certain point. Remember that one of the main purposes of Rosettacode is to provide a translation from one language to another. There are other places on the web for solving the problems in the best possible way. 2. There are no newlines (although the input is the list of lines to be "commatized" not concatenated.) write -> writeln 3. Zimbabwe dollars are given commas, against the explicit request to have dots. (That would be undesirable in the real world, not just in this silly example, because comma is used as a decimal point in the Zimbabwe press, and spaces for thousands separators.) Can be solved by calling the function with a right set of parameters: ins = '.'. That's what function parameters are for. 4. The second number in the line ===US$0017,440 millions=== (in 2,000 dollars) is "commatized" which is against the explicit instructions to "commatize" the first number only, given in the task description and explained on the task's talk page. replaceAll -> replaceFirst 5. The exponent in 123.e8000 is "commatized" which is against explicit and repeated instructions not to "commatize" exponents. replaceAll -> replaceFirst 6. (The commas in the Eddington number are acceptable enough.) OK. 7. The year in 6/9/1946 is "commatized" against explicit instructions to "commatize" only the first number field. It was discussed in the task's talk page that years shouldn't be commatized, and that's easy to avoid by never "commatizing" past the first number. replaceAll -> replaceFirst So, two custom calls, two minor changes, no sweat. Is everything right now? Even if not: that was fast, we can do another iteration. When we have a short readable solution with no special cases, the first few changes are going to be easy. For the Eddington number, the task didn't explicitly state to use spaces in that long a number, but the task does say there should be spaces in the digits of pi, which leaves open to interpretation whether that's a special request or a rule that could apply to any sufficiently long number, AND the task includes a reference to a Wikipedia page on the number that does use spaces. Here, I'd say you are greatly overthinking the problem. The other language solutions to Rosetta tasks may be "inspirational" in some ways, but there are also errors in them, at least for this task, that would be found if they were fully tested. They're made by human beings, and Rosetta code is just a game. It's not something that's been around as long as the older languages used there have existed, to look up to solutions in old languages with awe as time-worn and carved in stone. If you see a problem, ~10 solutions, and think all of them have serious issues, you may well be right. But it is also likely that all other solution authors read the problem differently. Which leaves an open formal question whether you are reading it correctly. As well as an open informal question whether enforcing your reading is a good goal, keeping in mind that Rosettacode is a collection of translations. - If you still insist you are doing the right thing and all others are wrong, let's agree to disagree on that, and please just leave the original solution there by introducing two versions. Ivan Kazmenko. I just now updated with a version that contains two functions: one function "commatize" very similar to the bearophile original but corrected, and the other my specialization "commatizeSpec" which calls commatize and processes all the example inputs programmatically. I didn't split those functions into two solution blocks, because they're not really separate, one calls the other, and they were compiled and tested together only, and they use the same two lines of compiled regex. That was a good challenge and good advice, to get called out on overcomplicating a function. I felt horrible about the complication, and enjoyed the simplification. One of the goals of Rosetta code I thought was to show the style in which things are done in different programming languages, their differences in capabilities, and idioms. That way you can translate what you want to do more idiomatically. If
Re: Rosetta Commatizing numbers
On Wednesday, 31 May 2017 at 04:31:14 UTC, Ivan Kazmenko wrote: On Tuesday, 30 May 2017 at 10:54:49 UTC, Solomon E wrote: I ran into a Rosetta code solution in D that had obvious errors. It's like the author or the previous editor wasn't even trying to do it right, like a protest against how many detailed rules the task had. I assumed that's not the way we want to do things in D. ... Does anyone have any thoughts about this? Did I do right by D? I'd say the previous version (by bearophile) suited the task much better, but both aren't perfect. As a general note, consider the following paragraph of the problem statement: "Some of the commatizing rules (specified below) are arbitrary, but they'll be a part of this task requirements, if only to make the results consistent amongst national preferences and other disciplines." This literally means that, while there are complex rules in the real world for commatizing numbers, the problem is kept simple by enforcing strict rules. The minute concerns of the Real World, like "Current New Zealand dollar format overrides old Zimbabwe dollar format", are irrelevant to the formal problem being solved. Perhaps the example inputs section ("Strings to be used as a minimum") gets misleading, but that's what they are: examples, not general rules. By the way, as it's a wiki page, problem statement text could also be improved ;) . Why? For example, look at Indian numbering system where commatizing is visibly different (https://en.wikipedia.org/wiki/Indian_numbering_system) - and we don't know whether the string should use it or not without the context. Or consider that hexadecimal numbers are usually split in groups of four digits, not three - and we don't know whether a [0-9]+ number is decimal or hexadecimal without the context. See, trying to provide an ultimate solution to real-world commatizing, while keeping it a single function without the context, can't possibly succeed. What can be done, then? Well, the page authors already did the difficult part for us: they extracted the essence of a complex real-world problem into a small set of formal rules, which are now the formal problem statement. Now comes the easy part: to do exactly what is asked in the problem statement. The flexibility comes from having function parameters. If we have a solution to a formal problem, using it for the real-world version of the problem is either just specifying the right parameters (hopefully), or changing the function if the real world gets too complex for it. In the latter case, the more short and readable the existing solution is, the faster can we change the function to suit our real-world case. - Now, where is the old version wrong? Turns out it just calls the function with default parameters for every line of input - which is wrong since the first two input lines need to be handled specially. Well, that's what the function parameters are for. To have a correct solution, we have to use custom parameters for the first two lines of input. The function itself is fine. Your solution addresses this problem by special-casing the inputs inside the function, perhaps because of the misleading inputs section in the problem statement. That's a wrong approach. First, it introduces magic numbers 33 and 36 into the code, which is a bad programming practice (see here: https://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants). Second, it's plain wrong. According to the problem statement, we don't have these rules for every possible line of >33 standalone decimals, or >36 characters in total. We just have to call our function with a concrete set of custom parameters for one concrete example, and other set of parameters for another example. That's to demonstrate that our function accepts and makes proper use of custom parameters! Special-casing example inputs inside the function is not a solution: if we go down this path, the perfect solution would be a bunch of "if" statements for every possible example input producing the respective example outputs, and empty function for all other possible inputs. So, how do we call with special parameters? Currently, we can look at every other language except C# as inspiration: ALGOL 68, J, Java, Perl 6, Phix, Racket, and REXX. Your solution also has a good way to check example inputs: a unittest block. It even shows one of D's strengths compared to other languages. And there, you do use custom parameters to check that the function works. A good approach would be to put all the examples in the unittest instead of reading them from a file. This way, the program will be immediately usable and runnable: no need to create an additional arbitrarily-named file just to test it. - All in all, the only thing I'd change in bearophile's solution is to remove the file reading loop, add the unittest block from your solution instead,
Rosetta Commatizing numbers
I ran into a Rosetta code solution in D that had obvious errors. It's like the author or the previous editor wasn't even trying to do it right, like a protest against how many detailed rules the task had. I assumed that's not the way we want to do things in D. Then I spent all day fixing it. Once I thought I had it working, I added some unittests, and realized it wasn't really correct, and struggled with the more complicated regex I had written, until it was simplified, and I really fixed it. So I pushed it, hard. The earlier version of the page made D look more error prone than other languages, but short. Now my solution is as long as some of the other language's solutions, but it's well commented and tested, I think. Now I doubt any of the solutions in other languages are as correct or potentially useful or informative. Something I removed was there was a commented out /* pure nothrow */ someone had left there, and a @safe attribute, because those don't work with using the parts of the library that I used. It seems like there's a tangle of features in the library that would take a lot more usage examples than what can fit in the library doc itself to sort out for people. Is it normal to add a bunch of wished-for future attributes to a function, then comment them out because they don't compile yet? Maybe that's something that happens often with D code, but I didn't think that should be how D is advertised. An extra that I could add, if I should push again, is using the compile time regex function ctRegex, but I found out that's not enough to make the function nothrow, by far. Does anyone have any thoughts about this? Did I do right by D? http://rosettacode.org/wiki/Commatizing_numbers
Re: hidden passing of __FILE__ and __LINE__ into function
On Tuesday, 18 April 2017 at 13:48:57 UTC, Stanislav Blinov wrote: On Tuesday, 18 April 2017 at 13:28:06 UTC, Solomon E wrote: I tried to produce an example of calling a function with variadic template arguments using special tokens __FILE__ and __LINE__. This compiles and runs, producing the output shown, using the default gdc provided by Ubuntu 17.04. This appears to be a workaround for Issue 8687... There's a much more concise workaround, both in code written and generated ;) import std.stdio; template func(string file = __FILE__, int line = __LINE__) { auto func(T...)(auto ref T args) { writeln("called func with ", T.length, " args at ", file, ":", line); } } void main() { func(); func(1, 2, 3); } Thank you for reminding me that templates can contain a definition of a function of the same name, which still surprises me as convenient, not as a bad thing. Unfortunately, when I tried it, I found that while that attempt at a workaround is twice as concise in lines of code and symbols introduced, it is not acceptable. It gets the lines reported wrong. It reports the line for where the template was first instantiated for the same tuple of argument types, instead of exactly the line of each call of `func`.
Re: hidden passing of __FILE__ and __LINE__ into function
On Tuesday, 18 April 2017 at 10:13:09 UTC, Jonathan M Davis wrote: On Monday, April 17, 2017 07:23:50 Jonathan M Davis via Digitalmars-d-learn wrote: So, if you're okay with explicitly instantiating your variadic function template instead of having the types inferred, then it can work, but otherwise, no. Making it work would require a language enhancement Actually, not only is there already a bug report for this https://issues.dlang.org/show_bug.cgi?id=8687 which is marked as a bug and not an enhancement, and when Walter commented on it when an ICE related to it was fixed, he didn't change it from a bug to an enhancement. So, it looks like he agrees that it's a bug rather than considering it an enhancement. It has yet to be fixed regardless though. - Jonathan M Davis import std.stdio: writeln; import std.conv: to; void main() { add("Scene 1", "Scene 2", "Scene 3"); add("Scene 3", "Scene 4", "Scene 5"); add(5, 6, 7); add(7, "Scene 8", "Scene 9"); writeln("total scenes added: ", sceneCount); } struct Scene { string name; string file; size_t line; } Scene*[] listOfScenes; int[string] indexOfScenes; int sceneCount = 0; void add_impl(T...)(string file, size_t line, T args) { foreach(arg; args) { static if (is(typeof(arg) == string)) { auto name = arg; } else { auto name = "Scene " ~ arg.to!string; } if (name in indexOfScenes) { EError(file, line, "scene already exists", name); } else { indexOfScenes[name] = sceneCount; listOfScenes ~= new Scene(name, file, line); sceneCount += 1; writeln("added " ~ name); } } } void add(string file = __FILE__, size_t line = __LINE__, T...)(T args) { add_impl!T(file, line, args); } void EError(string file, size_t line, string message, string name) { writeln(name, ": ", message, " in file ", file, " in line ", line); auto previous = listOfScenes[indexOfScenes[name]]; writeln("previous definition of ", previous.name, " was in ", previous.file, " in line ", previous.line); } /* output: added Scene 1 added Scene 2 added Scene 3 Scene 3: scene already exists in file vlf.d in line 7 previous definition of Scene 3 was in vlf.d in line 6 added Scene 4 added Scene 5 Scene 5: scene already exists in file vlf.d in line 8 previous definition of Scene 5 was in vlf.d in line 7 added Scene 6 added Scene 7 Scene 7: scene already exists in file vlf.d in line 9 previous definition of Scene 7 was in vlf.d in line 8 added Scene 8 added Scene 9 total scenes added: 9 */ I tried to produce an example of calling a function with variadic template arguments using special tokens __FILE__ and __LINE__. This compiles and runs, producing the output shown, using the default gdc provided by Ubuntu 17.04. This appears to be a workaround for Issue 8687. The instantiations of the wrapper function `add` should only add minimally to the compiled object code size, once per call of `add`. I'm not sure about the quality of any of this code.
Re: Collapsing n-dimensional array to linear (1 dimensional)
On Saturday, 23 January 2016 at 07:57:55 UTC, Ali Çehreli wrote: auto collapse(R)(R r) if (isArray!R) { return r.joiner.collapse.joiner; } auto collapse(R)(R r) if (!isArray!R) { return r; } Ali, that code only passed the one test it had for collapsing a three level array. It wouldn't collapse arrays of other numbers of levels. It wasn't recursing as appeared to be intended. Is the following code better D? (I don't know because I'm still learning D, so I'd like to be corrected if the comments in my code are inaccurate or misleading.) (See https://issues.dlang.org/show_bug.cgi?id=12062 for where I got the idea that `flatten` should be defined to mutate by reference. A comment there suggests to use std.experimental.ndslice and byElement for that, but ndlslice doesn't seem to be in the library anymore.) import std.stdio; import std.range; import std.algorithm; import std.traits; /** `collapse` returns an array that can be type inferred * and can be cast to [] without effect */ auto collapse(R)(R r) if (isArray!(ElementType!R)) { return r.joiner.array.collapse; } auto collapse(R)(R r) if (!isArray!(ElementType!R)) { return r; } /** `flatten` returns a range Result that can modify the original by ref * and .flatten.array is equivalent to .collapse */ auto flatten(R)(R r) if (isIterable!R && isIterable!(ElementType!R)) { return r.joiner.flatten; } auto flatten(R)(R r) if (!(isIterable!R && isIterable!(ElementType!R))) { return r; } unittest { auto r1 = 3.iota.array; auto r2 = 3.iota.map!(i => iota(3 * i, 3 * i + 3).array).array; assert(r2 == [[0,1,2],[3,4,5],[6,7,8]]); auto r3 = 3.iota .map!(i => iota(3 * i, 3 * i + 3) .map!(j => iota(3 * j, 3 * j + 3) .array) .array) .array; auto r4 = 3.iota .map!(i => iota(3 * i, 3 * i + 3) .map!(j => iota(3 * j, 3 * j + 3) .map!(j => iota(3 * j, 3 * j + 3) .array) .array) .array) .array; auto r5 = 3.iota .map!(i => iota(3 * i, 3 * i + 3) .map!(j => iota(3 * j, 3 * j + 3) .map!(j => iota(3 * j, 3 * j + 3) .map!(j => iota(3 * j, 3 * j + 3) .array) .array) .array) .array) .array; writeln("\nOriginal 1 level:\n", r1); writeln("Collapsed:\n", r1.collapse); writeln("\nOriginal 2 level:\n", r2); writeln("Collapsed:\n", r2.collapse); writeln("\nOriginal 3 level:\n", r3); writeln("Collapsed:\n", r3.collapse); writeln("\nOriginal 4 level:\n", r4); writeln("Collapsed:\n", r4.collapse); writeln("\nOriginal 5 level:\n", r5); writeln("Collapsed:\n", r5.collapse); // equality (collapse is eager and iota is lazy) assert(r1.collapse.equal(iota(3))); assert(r2.collapse.equal(iota(9))); assert(r3.collapse.equal(iota(27))); assert(r4.collapse.equal(iota(81))); assert(r5.collapse.equal(iota(243))); // value equality assert(r1.collapse == iota(3).array); assert(r2.collapse == iota(9).array); assert(r3.collapse == iota(27).array); assert(r4.collapse == iota(81).array); assert(r5.collapse == iota(243).array); // cast is allowed and does not affect the result assert(cast(int[]) r1.collapse == iota(3).array); assert(cast(int[]) r2.collapse == iota(9).array); assert(cast(int[]) r3.collapse == iota(27).array); assert(cast(int[]) r4.collapse == iota(81).array); assert(cast(int[]) r5.collapse == iota(243).array); // type inference auto ar1 = r1.collapse; assert(ar1 == iota(3).array); auto ar2 = r2.collapse; assert(ar2 == iota(9).array); auto ar3 = r3.collapse; assert(ar3 == iota(27).array); auto ar4 = r4.collapse; assert(ar4 == iota(81).array); auto ar5 = r5.collapse; assert(ar5 == iota(243).array); // lazy equality assert(r1.flatten.equal(iota(3))); assert(r2.flatten.equal(iota(9))); assert(r3.flatten.equal(iota(27))); assert(r4.flatten.equal(iota(81))); assert(r5.flatten.equal(iota(243))); // equivalence between .flatten.array and .collapse assert(r1.flatten.array == ar1); assert(r2.flatten.array == ar2); assert(r3.flatten.array == ar3); assert(r4.flatten.array == ar4); assert(r5.flatten.array == ar5); // mutation by reference through a flatten foreach (ref x; r3.flatten) { x++; } writeln("r3 scalar incremented ", r3); auto r3i = iota(1, 4) .map!(i => iota(3 * i - 2, 3 * i + 1) .map!(j => iota(3 * j - 2, 3 * j + 1)
Instructions for compilation from multiple source files
I wanted to know how to compile a D program that has multiple source files. I looked under Modules in the language reference, but there isn't anything there about compilation, or anything about where to put the source files, or anything about how the compiler finds the files to use. I'm currently using the GDC compiler, because I don't trust the DMD Debian package enough to install it, considering it has Google adsense ads in its HTML pages, which is against even Google's policy. I looked around the D Wiki for instructions on compilation, and it doesn't seem that there are any instructions other than for DMD on Windows and for compiling a hello world with one source file. The GDC site has no instructions or documentation on how to do compilation. The GDC man page is the same as the GDC info page. It lists some options for the compiler without listing what they do in the case of D. I'm not getting any .o or .a files out of the compiler, only a.out or whatever file name I choose with the -o option. I don't want to have to guess how to do it and experiment, as if it's all implementation defined and in flux to the degree that that's the only way to compile anything. If there aren't instructions or documentation on how to compile more than one file into a finished D runnable project in a correct way that can grow with larger projects, then I'll have to take it as implied that D is just not ready or not welcoming and I shouldn't use it.
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 12:21:51 UTC, bearophile wrote: It's not in flux. A simple way to compile more than one file is to put them in the same compilation unit (almost the same if you want to create a lib): dmd a.d b.d Otherwise you can also use ddmd and let it find the module dependencies by itself. Bye, bearophile That's not applicable because I'm not using DMD. Also that doesn't answer where a .o or .a file comes from, whether there's any difference between them besides the name, and if so what. I've compiled a lot of little examples and tests of D from single source files, but I haven't seen any .o or .a files yet. I was hoping there were instruction pages or documentation pages on how to compile D projects that have multiple source files.
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 12:49:46 UTC, ketmar via Digitalmars-d-learn wrote: you'd better not use command-line toolchain, they all aren't ready. if you can't figure out how to use some compiler of GCC suite, you'd better try some IDEs. So there's such a lack of documentation on D that I'm *supposed* to just guess and experiment about what .o and .a files might be, or hope that an IDE frontend writer guessed right? There's no specification whatsoever?
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 13:11:45 UTC, Russel Winder via Digitalmars-d-learn wrote: ketmar was just being a teensy weensy bit over-dramatic. He was trying to point out that gdc is part of the GCC and so all the GCC documentation is relevant for gdc. D thus gets huge amounts of documentation for gdc for free. The problem that I'm having with this seems to be with GDC, not the rest of the D community. The following is a quote of the entire amount of information in the GDC man page on the following compiler options and file extensions: SYNOPSIS gdc [-c] [-g] [-pg] [-Olevel] [-Idir...] [-Ldir...] [-o outfile] infile... For any given input file, the file name suffix determines what kind of compilation is done: file.d D source files. file.di D interface files. file.o Object files to link in. file.a Library files to link in So I could *guess* that a dot o file is the equivalent of a .obj file an Windows, and *guess* that a dot a file is the equivalent of a .lib file on Windows, then follow some Windows instructions as on the page http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows but I would totally be guessing, and I still wouldn't know where to get any .a files, but I could *guess* that I would get a .o file by running the compiler and naming the output a .o file by using the -o switch. I would be totally guessing, and if I'm wrong, all my builds would be wrong and incompatible with other people's build systems. Again, I was hoping there would be some instruction pages or documentation pages or specifications on this subject.
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 13:44:26 UTC, ketmar via Digitalmars-d-learn wrote: you'd better use some IDE if you have to guess such things. gdc manpage documents gdc-specific options. it even gives you some directions in see also section, which you are supposed to follow to read more about GCC suite. GCC also has extensive on-line documentation. yes, you are supposed to know how to use GCC, part of which gdc is. if you don't want to think about that, you can use IDE which does all this for you automatically. I keep saying I want documentation or specifications. If there isn't any, how would the people who write the IDE frontends for languages know whether they're doing it right? Maybe they aren't and they're just guessing and naming output files whatever way sounds and looks right to them, so it sort of fits with what output people expect, without actually being the right format of files! (I quoted from the GDC man page. How do you think I did that if it wasn't for reading it?) Some pages say to rename output files with .a if you want a library type file, other pages say they're an archive format for library files. So this isn't idle speculation that there might be some confusion by tool writers or there might be a lack of enough officially specified standards or accessible enough documentation. http://rainers.github.io/visuald/visuald/Installation.html quote when building a library you should change the output file name extension to .a. end quote
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 15:35:54 UTC, ketmar via Digitalmars-d-learn wrote: On Mon, 10 Nov 2014 14:12:12 + Solomon E via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: I keep saying I want documentation or specifications. and i keep saying that if you can't find those for you case, you'd better stick with IDE. you keep ignoring the fact that gdc is a part of GCC and you have to read GCC documentation to understand the process. ok, it's your right to insist that gdc must include GCC documentation, but don't expect it to happen, as this will be a useless duplication. any person that is familiar with GCC suite immediately groks how to use gdc, 'cause it's not different from other GCC frontends. sure, it has some specific options, and those options are documented in manpage. if you don't want to see gdc as a part of GCC suite... oh, well, it's your choice. other gdc users has no problems with that and they aren't refusing to understand how GCC should be used, what files it produces and how. as you obviously don't want to learn that, i keep recommending you to use IDE for working with your code, 'cause IDE knows how to call requred tools from the toolchain. I do know about how to use GCC and where the documentation for that is. I know what .o files and .a files are in terms of GCC for C, because there's tons of documentation about that. I thought that there might be a little bit of documentation about what they are for D, or a specification. A language that's about grokking things (I've read Stranger in a Strange Land, so I grok what it means) is not the sort of language that I want to use. I prefer that a language that specifies what a computer is to do be specified itself. That is all. I don't want to use an IDE that pretends to have AI about what to do for me, just because a language doesn't have enough documentation to let me know what to do for myself. That's like the opposite of learning to program. In this case it's about the tiny amount of documentation for GDC, which assumes that users will know about using GCC for C or C++ and will apply a diff of how D differs from those to use it for D. In other cases I've seen all over the Language Reference it's the same thing: D is described roughly as a diff of C and C++ and not as a language in its own right, with examples that may or may not be complete and who can tell where they are complete enough and where they aren't?
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 16:49:27 UTC, John Colvin wrote: On Monday, 10 November 2014 at 12:10:37 UTC, Solomon E wrote: I don't trust the DMD Debian package enough to install it, considering it has Google adsense ads in its HTML pages, which is against even Google's policy. Could you point to the exact page your looking at? Gdebi Package Installer gave privacy-breach-google-adsense as a Lintian output for about a hundred pages in dmd_2.066.0-0_amd64.deb (as well as a lot of other problems I don't know about.) https://lintian.debian.org/tags/privacy-breach-google-adsense.html I tried extracting the pages in question and viewing them, and yes, they do serve Google ads from online while browsing local html files.
Re: Instructions for compilation from multiple source files
On Monday, 10 November 2014 at 19:09:45 UTC, ketmar via Digitalmars-d-learn wrote: as for D... they are compiled object files. exactly the same thing as for c++, gnu pascal or any other language in GCC that produces .o. are you expecting them to be something special? then you'll read about that in gdc manpage. That's nice. That implies all those compiled object files are compatible regardless of language. I don't know if that's true. It seems doubtful to me. how this belongs to particular D compiler? you are *expected* to understand what is being part of GCC suite for GNU D compiler. it's not about language at all, it's about toolchain. and this is not the only one compiler available, and there inevitably will be more. do you expecting to read about every specific compiler implementation in language dox? DMD happens to be special one 'cause it's a reference compiler for D. yet there is nothing special in DMD, it's an ordinary command-line compiler. if you know how to use one of them, you know how to use all of them. I thought part of learning D would be learning to compile larger programs than hello world. So I thought D.learn would be the correct forum to ask a question about where the documentation or specifications are for the files types involved in D on Linux, if any. I disagree that knowing how to use one command line compiler means knowing how to use all command line compilers. Maybe there have been a few more command line compilers in computer history than you're taking account of. should D documentation include all all POSIX documentation for core utils, 'cause some of them can be needed to work with source files? and for VIM, and for Emacs and for all other editors, 'cause, ahem, they can be used to edit D sources? you are *expected* to know how your system works, what file and directory is, what is compiling to object file, what is linking and so on. if there is something that deviates from common system way of doing things, only then it is documented. like gdc-specific command line arguments. I've run across a similar attitude before. When I tried MinGW and GCC the first time to use C, there were no instructions on the whole MinGW site for how to compile even a hello world using it for C, only for C++ instead. When I sent a message about that, also mentioning that I was somewhat confused by what sort of shell MinGW produced, what was it exactly, I was told it was bash and directed to the Beginner's Guide to Bash, which I found I couldn't use according to that guide's own instructions, because I wasn't already experienced in installing and running programs on a Unix-like system, which that guide says is a prerequisite. (Of course I got going and did what I wanted to do with C anyway. Those were just some learner's questions, normal for learning a different computer program with incomplete instructions, I thought. Apparently some experienced Unix-like system users have a different attitude.) It's true, you are expected to know your system, even if it's brand new to you and the instructions are only for experienced users and warn you away from using them if you aren't an experienced user yet. This is a problem. Why not just somewhere have a few lines of examples and type signatures for the various elementary commands for a compiler, as part of the documentation or specification that it's supposed to meet in order to be considered functional? I'm not asking for that to be in the D language specifications, because it is about GDC. it's the easiest way to describe such things. i don't see how it is necessary to copy and paste all GCC documentation for gdc. In other cases I've seen all over the Language Reference it's the same thing: D is described roughly as a diff of C and C++ you realised that language reference is not meant for those who learning how to program, didn't you? there is the excellent book by Ali Çehreli which is not diff and targeted to those who learning D, for example. and then you are expected to read documentation for GCC if you are planning to use gdc, as gdc is a part of GCC. there is nothing unsusual in not finding the information you want if you are looking for it in the wrong place. physics textbook will not start with teaching you simple math. I already downloaded and started working through the examples in that book a couple of weeks ago. The sort of assumption I'm talking about is here again, that doing the simplest things with a compiler is like simple math in your analogy. If someone has been using similar compilers for years and years, I suppose it seems so. People seem to lose sight of the fact that computer programs allow fully arbitrary interpretation of commands and their results. So whatever a person guesses about how it works or reads in a textbook about some other program or a related program with a similar name or similar commands might not apply to the program a person wants to use. In this whole thread, I
Re: Instructions for compilation from multiple source files
ketmar, I understand that GDC documentation can be as terse as it wants to be, especially in the man page, which is supposed to be the shortest, for quick command line reference. It still seems a little odd to me that there wouldn't be additional instructions somewhere in the introductory pages to D on the D Wiki or somewhere else conveniently linked, on compiling multiple input files that are applicable to GDC or to all three compilers, rather than just specific to DMD on Windows. There's a joke in mathematics that sometimes a hard, unsolved problem is passed over in a paper with the words the rest is left as an exercise for the reader. Leaving the subtleties of multiple file GDC usage as an exercise, whatever those may be for D, if any, is certainly better than omitting language documentation or development or bugfixes, and also better than not having multiple compilers to choose from. So on reflection, I agree with leaving multiple file command line GDC usage as an exercise for anyone who wants to do it, in order to conserve limited development resources for improving more important things about D. So I'm sorry about all the fuss. I would delete the thread if I could. I understand that you're implying multiple file compilation should go smoothly the same for D as it does for any other GCC supported language, without any particular difficulties for D that you've seen about it, and I hope it goes smoothly for me as well.
Re: Instructions for compilation from multiple source files
It all works fine for me so far. I wrote a trivial test project of four d files, and compiled it all together, directly from d files, which took a couple of seconds to compile. Then instead I compiled it as two o files in an a file (using ar to archive), plus a d file, plus another o file for good measure, and that was faster on the final compile time.
Re: Global const variables
On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote: On Tuesday, 21 October 2014 at 08:25:07 UTC, bearophile wrote: Minas Mina: Aren't pure functions supposed to return the same result every time? If yes, it is correct to not accept it. But how can main() not be pure? Or, how can't the 'a' array be immutable? Bye, bearophile There can exist a mutable reference to a's underlying memory: const int[] a; int[] b; static this() { b = [1]; a = b; } `a` isn't a reference to `b`. `a` is assigned by value and has its own storage. You could change its type to const int[]* a = b; then it would be a reference to mutable storage. I made an example program to figure these things out, or else I wouldn't know what I'm talking about. import std.stdio; import std.conv; const int[] a; int[] b; static this() { string entry; while(entry == ) { try { write(enter an int: ); entry = readln(); b = [to!int(entry[0..entry.length-1])]; } catch(ConvException e) { writeln(error, try again); entry = ; } } a = b; } int[] x = [0,1,2,3]; class Holder { const(int[]) y; this() { y = x; } } void main() { auto H = new Holder(); writeln(original const a , a); // [the int that was entered] b = [8,7]; writeln(unaltered const a , a); // [the int that was entered] x = [10,9]; writeln(unaltered const member y , H.y); // [0, 1, 2, 3] H = new Holder(); writeln(new const member y , H.y); // [10, 9] writeln(immutable m , get_m()); // [42] } immutable int[] m = [42]; immutable(int[]) get_m() pure { return m; }
Re: Global const variables
On Tuesday, 21 October 2014 at 12:30:30 UTC, anonymous wrote: On Tuesday, 21 October 2014 at 12:08:35 UTC, Solomon E wrote: On Tuesday, 21 October 2014 at 08:48:09 UTC, safety0ff wrote: const int[] a; int[] b; static this() { b = [1]; a = b; } `a` isn't a reference to `b`. `a` is assigned by value and has its own storage. `a` is indeed a copy of `b`. But `b` is a pointer+length, and only those are copied. The array data is not copied. `a` and `b` refer to the same data afterwards. [...] const int[] a; int[] b; static this() { [...] a = b; } [...] void main() { [...] b = [8,7]; Here, making `b` point somewhere else (to [8, 7]). If instead you change b's elements, you'll see that `a` and `b` refer to the same data: b[] = 8; /* Will also change `a`'s data. */ You're right. Thank you, anonymous stranger. Sorry about that, safety0ff. It looks like you were right and I was wrong. `b[0] = 8;` or `b[] = 8;` changes a. Printing the values for a and b shows they're different pointers, but (a is b) returns true. So I still have more to learn about how it does that.
Re: Global const variables
On Tuesday, 21 October 2014 at 14:25:20 UTC, ketmar via Digitalmars-d-learn wrote: On Tue, 21 Oct 2014 13:43:29 + Solomon E via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: `b[0] = 8;` or `b[] = 8;` changes a. Printing the values for a and b shows they're different pointers, but (a is b) returns true. So I still have more to learn about how it does that. that's 'cause 'b' taking address of hidden array structure, not the first array element, as in C. try 'a.ptr' and 'b.ptr' to get addresses of array elements. Thanks, that's what I was looking for, in order to understand what's going on. I Googled for it on this site, but without remembering the keyword ptr, I didn't find anything relevant. After I put printouts of .ptr in my test program, I figured out how to get the same result by unsafe pointer arithmetic. Apparently, for an array a, a.ptr == *(cast(ulong*) a + 1). That's unsafe because the implementation might change, and pointer arithmetic is unsafe in general.
Re: Global const variables
On Tuesday, 21 October 2014 at 15:51:27 UTC, MachineCode wrote: ... ... pure functions are also supposed to don't use global variables at all, according to functional programming paradigm Pure functions are immutables (constants but not const in the D or C++ senses) and can use other immutables, even if they're global immutables. (I guess it would be better though always to have a named top scope instead of everyone in the world having the same global scope :-)
Does the grammar allow an alias statement without a semicolon?
Hi, everyone, first post here. I'm trying to learn to parse D code. The line alias StorageClassesopt BasicType Declarator in http://dlang.org/grammar#AliasDeclaration is apparently missing a semicolon after Declarator. If that line is not missing a semicolon, could someone please explain how it's possible to parse D, given that according to the grammar with that line taken literally, some statements may come after each other without a semicolon, and some statements may end with one of the keywords const, immutable, inout, or shared, which are keywords that come at the beginning of some other statements?
Re: Does the grammar allow an alias statement without a semicolon?
Thank you both. That DGrammar project has some different names for the nonterminals in its grammar, and a different arrangement, but it confirms there should be a semicolon with any alias statement. I'm just trying to parse D when I read it myself so far, and figure out how the grammar works a little. I'm not trying to write a parser for it, at least not yet.