Re: Diva - D Language Interface for Versioned Applications
On Sunday, 11 July 2021 at 13:39:15 UTC, Jacob Carlborg wrote: Some other differences: * DVM is cross-platform. Diva seems to only run on Ubuntu. * DVM is implemented in D (with a tiny shell script wrapper). Diva depends on Python * DVM does not use symlinks. When invoking the compiler it's the actual executable that's invoked directly * DVM provides a built-in command to install itself and do any setup -- /Jacob Carlborg Fair points here. It's stated in the readme but just to be really clear: I wrote this mainly for my own use. It may or may not work for you out-of-the-box. I put it on GitHub with an MIT license in case it might be useful to others. It's definitely not a polished production-ready piece of software. * DVM is cross-platform. Diva seems to only run on Ubuntu. Well, not exactly. I wrote Diva in a couple of evenings this past week and I haven't had an opportunity to test it on other platforms than Ubuntu so far. I'm confident it will work with other Linux distros (though it might have problems on ARM platforms; it can't build DMD or LDC from source yet which means if there's not a prebuilt binary then Diva can't help you) and I'm reasonably sure it will work with MacOS without any changes. There's a fair chance it will break down on Windows. Even though there's some logic specifically to try to handle Windows, I just haven't tested it yet. If you want to use it on your platform and run into difficulties, the script is fairly simple and fairly well documented and so hopefully feasible to troubleshoot things for yourself. I'm happy to accept a PR if you find and fix issues like this. * DVM is implemented in D (with a tiny shell script wrapper). Diva depends on Python Yep. It was faster for me to write it in Python. I'm personally much more familiar with Python's tools for making HTTP requests and for extracting compressed archives than I am with D's, and my goal here was to just have something usable for myself in little time. If someone wanted to rewrite Diva in D and make sure there's a handy script to bootstrap it if a D compiler isn't already locally available, that would be fantastic. * DVM does not use symlinks. When invoking the compiler it's the actual executable that's invoked directly Yep, symlinking is a fairly standard way to handle this sort of thing, and it's how I wanted to do it on my system. If you prefer to do it differently on your system, you could take Diva's downloading and installation system as a starting point and revise its "use"/"disuse" logic. If it's compatible/configuration-switchable with the symlink implementation, I'd be happy to accept a PR that added this sort of thing. * DVM provides a built-in command to install itself and do any setup Yep, the Diva install process is very slightly more complicated in that you will have to find your bashrc (or equivalent) on your own after using `pip install .` and paste a few lines in according to the instructions in the readme.
Re: Diva - D Language Interface for Versioned Applications
On Saturday, 10 July 2021 at 08:42:46 UTC, Bastiaan Veelo wrote: Could it be that you have overlooked D Version Manager? https://code.dlang.org/packages/dvm — Bastiaan. Oh, I hadn't picked up on that. That only manages DMD, though. Diva can manage DMD and LDC, as well as managing dub separately if you want it to. Personally I'll be using Diva in the future to manage my installations.
Diva - D Language Interface for Versioned Applications
Basically, it's a version manager which currently supports DMD, LDC, and dub. It's rough, but maybe in some ways a little less rough than install.sh, at https://dlang.org/install.html https://github.com/pineapplemachine/diva
Re: Where is there documentation on how to write inline asm?
Well, for anyone who is tangling with similar mysteries, I finally got something to work the way I wanted it to. Thank you for the help, Adam and kinke! The first "x" argument was stored in R8. The second "y" argument was stored in RDX. The invisible return value pointer was stored in RCX. Here's what I was hoping to accomplish. The multiply function returns the low bits of the product in the `low` attribute of the struct and the high bits in the `high` attribute of the struct. The divide function returns the quotient in `low` and the remainder in `high`. struct Result { ulong low; ulong high; } Result unsignedMultiply(ulong x, ulong y) { version(D_InlineAsm_X86_64) asm { naked; mov RAX, R8; mul RDX; mov qword ptr [RCX], RAX; mov qword ptr [RCX + 8], RDX; ret; } } Result unsignedDivide(ulong x, ulong y) { version(D_InlineAsm_X86_64) asm { naked; mov RAX, R8; mov R9, RDX; mov RDX, 0; div R9; mov qword ptr [RCX], RAX; mov qword ptr [RCX + 8], RDX; ret; } }
Re: Where is there documentation on how to write inline asm?
Ah, I've got something working! It's not exactly what I wanted, but it's good enough for now. Instead of using an invisible output pointer, the output pointer is passed in explicitly. struct Result { ulong low; ulong high; } void retTest(Result* result) { version(D_InlineAsm_X86_64) asm { naked; mov [RAX + 0], 0x80; mov [RAX + 8], 0xff; ret; } }
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:48:46 UTC, kinke wrote: The MS docs are complete IIRC. The pointer to the pre-allocated result of your 16-bytes struct is passed in RCX. If unsure, just reverse-engineer what you need: type it down in normal D and analyze the generated assembly. You can even do so online via run.dlang.io (https://run.dlang.io/is/rhsDBF); just select LDC and add `-mtriple=x86_64-pc-windows-msvc` to generate Win64 assembly. Note that run.dlang.io displays AT asm, not the Intel one. You can use LDC offline via `-output-s -x86-asm-syntax=intel` to generate a .s file with Intel syntax. When I tested by writing to the pointer given by RCX, the program didn't crash but I did get different values every time and never the ones I wanted.
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:12:39 UTC, Adam D. Ruppe wrote: On Thursday, 15 November 2018 at 21:07:51 UTC, pineapple wrote: Is there a way to access this pointer? It is passed as.. I think the final argument to the function. (unless it is the first, do a quick test to find out). Also, the calling convention documentation there doesn't mention anything about 64-bit targets, are 64-bit registers just not used? It uses the C rules there, so look up the 64 bit C abi. I think this is accurate https://msdn.microsoft.com/en-us/library/ms235286.aspx On the positive side: I see now how to return a 64-bit value from a function in Windows x64! And I understand how the arguments are coming in. This is very helpful. On the less positive side: I still have no clue how to return my 16-byte struct. The Microsoft x64 ABI documentation I've seen so far explains how return values of 8 bytes and fewer work, but haven't explained how larger return values work. The obvious answer of "RAX or EAX contains a pointer" is either not working or my asm is wrong. (The latter is certainly a possibility.) // Returns 128 (0x80) ulong retTest() { version(D_InlineAsm_X86_64) asm { naked; mov RAX, 0x80; ret; } } // Crashes struct Result { ulong low; ulong high; } Result retTest() { version(D_InlineAsm_X86_64) asm { naked; mov [RAX + 0], 0x80; mov [RAX + 8], 0x80; ret; } } // Also crashes struct Result { ulong low; ulong high; } Result retTest() { version(D_InlineAsm_X86_64) asm { naked; mov [R9 + 0], 0x80; mov [R9 + 8], 0x80; ret; } }
Re: Where is there documentation on how to write inline asm?
On Thursday, 15 November 2018 at 21:00:10 UTC, Adam D. Ruppe wrote: It would be part of the abi: https://dlang.org/spec/abi.html#function_calling_conventions though it references C so you might need to look that up too. That's helpful, thank you! For other sized structs and static arrays, the return value is stored through a hidden pointer passed as an argument to the function. Is there a way to access this pointer? Also, the calling convention documentation there doesn't mention anything about 64-bit targets, are 64-bit registers just not used?
Where is there documentation on how to write inline asm?
I've managed to get a few functions working before mostly by copying whatever Phobos was doing for a similar purpose, but now that I'm trying to do something different I am really hitting a wall. My issue is that I can't figure out how to access a function's arguments from within inline asm or how to ensure that the correct value is returned. I haven't found a single piece of documentation about this so far! I am mainly concerned about doing this for naked asm functions, but any documentation on the subject would be helpful.
Re: Running tests for a large library on Windows
Speaking of which, is there any AppVeyor config or script laying around somewhere for how to install 64-bit DMD? Since I would ideally like to automate testing with both 32-bit and 64-bit DMD
Running tests for a large library on Windows
I do mach.d - https://github.com/pineapplemachine/mach.d I've been setting up CI tests and OSX and Linux tests are good to go thanks to Travis. I'm having a little more difficulty with testing on Windows via AppVeyor, since DMD is too memory-hungry to `dub test` without a fatal error when DMD was compiled for a 32-bit target as opposed to 64-bit, as is the case for all Windows releases. How can I compile and run unit tests for only a part of the library at a time, so that 32-bit Windows can run tests too? (Which is actually important, since there are different x86 and x86-64 implementations of some library functions.) Or is there another solution? It's my understanding that phobos would have a similar problem if it didn't do something deliberate with how tests are run.
Stack traces with DMD on OSX
When I run code on OSX and it produces a stack trace, the output uses mangled symbols and is missing line numbers, like so - how can I change these stack traces to be more readable? 0 objectpool 0x000104e9a3bc _D4core7runtime18runModuleUnitTestsUZ19unittestSegvHandlerUNbNiiPS4core3sys5posix6signal9siginfo_tPvZv + 56 1 libsystem_platform.dylib0x7fff8bd5b5aa _sigtramp + 26 2 ??? 0x0002 0x0 + 2 3 objectpool 0x000104ea994b D2gc4impl12conservative2gc14ConservativeGC200__T9runLockedS79_D2gc4impl12conservative2gc14ConservativeGC12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS40_D2gc4impl12conservative2gc10mallocTimelS40_D2gc4impl12conservative2gc10numMallocslTmTkTmTxC8TypeInfoZ9runLockedMFNbKmKkKmKxC8TypeInfoZPv + 147 4 objectpool 0x000104ea3463 D2gc4impl12conservative2gc14ConservativeGC6qallocMFNbmkxC8TypeInfoZS4core6memory8BlkInfo_ + 115 5 objectpool 0x000104ea26a3 gc_qalloc + 51 6 objectpool 0x000104eaf5a8 D2rt8lifetime12__arrayAllocFNaNbmxC8TypeInfoxC8TypeInfoZS4core6memory8BlkInfo_ + 236 7 objectpool 0x000104eb3d9a _d_arrayliteralTX + 102 8 objectpool 0x000104cf7c2c D4mach3sys6memory19__unittestL120_1062FZv + 240 9 objectpool 0x0001049f8496 _D4mach3sys6memory9__modtestFZv + 14 10 objectpool 0x000104e9a409 D4core7runtime18runModuleUnitTestsUZ14__foreachbody2MFPS6object10ModuleInfoZi + 45 11 objectpool 0x000104e9067f D6object10ModuleInfo7opApplyFMDFPS6object10ModuleInfoZiZ9__lambda2MFyPS6object10ModuleInfoZi + 35 12 objectpool 0x000104eb5c56 D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZ14__foreachbody2MFKS2rt19sections_osx_x86_6412SectionGroupZi + 86 13 objectpool 0x000104eb5be1 D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZi + 33 14 objectpool 0x000104e90656 D6object10ModuleInfo7opApplyFMDFPS6object10ModuleInfoZiZi + 34 15 objectpool 0x000104e9a2f3 runModuleUnitTests + 127 16 objectpool 0x000104eaddc3 D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 23 17 objectpool 0x000104eadd5c D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 32 18 objectpool 0x000104eadcc7 _d_run_main + 459 19 objectpool 0x0001049f8caa main + 34 20 libdyld.dylib 0x7fff854835fd start + 1
Re: Why think unit tests should be in their own source code hierarchy instead of side-by-side
I really like `unittest`. It's my personal conviction that a developer should not be able to view the documentation, tests, or implementation for some part of a code base in isolation. `unittest` makes it easier for me to work this way. Automated tests are vital for stability and documentation is vital for maintainability and making it possible for others to understand your code. But when they aren't right there in the same place as the implementation, I've noticed that it is the inevitable habit of developers to think of tests and documentation as second-class, if they are thought of at all. The developer updates the implementation and doesn't think to update the tests or the docs. This happens a few times. Then instead of updating the tests to work with the updated implementation, the tests are discarded as an inconvenience. And then end users become confused by docs that have since become inapplicable.
Re: Best syntax for a diagonal and vertical slice
On Saturday, 22 July 2017 at 20:55:06 UTC, kerdemdemir wrote: And what if I want to go diagonal like 1,5,9 or 3,5,7 in the example above. Is there a good solution in std without using for loops? I suggest using an actual matrix type for tasks like this. I don't know about diagonal slicing, but the implementation here at least provides accessors for both rows and columns. https://github.com/pineapplemachine/mach.d/blob/master/mach/math/matrix.d
Re: map on char[] converts to dchar?
It is worth noting too that mach's map function will not behave this way; UTF encoding and decoding is instructed explicitly and is not done implicitly like in phobos. https://github.com/pineapplemachine/mach.d import mach.range : map, asarray; import mach.text.ascii : toupper; void main(){ char[] x = ['h', 'e', 'l', 'l', 'o']; char[] y = x.map!toupper.asarray(); assert(y == "HELLO"); }
Re: Lookahead in unittest
On Friday, 12 May 2017 at 21:23:23 UTC, Steven Schveighoffer wrote: Note, you can achieve what you want with version(unittest): Please prefer `private version(unittest){...}` if the module might be imported by someone else's code, as to not pollute it with unneeded symbols
Re: Split Real / Float into Mantissa, Exponent, and Base
On Friday, 3 March 2017 at 18:09:02 UTC, Jonathan M. Wilbur wrote: I have tried to come up with a good way to get the mantissa, exponent, and base from a real number, and I just can't come up with a good cross-platform way of doing it. I know about std.math.frexp(), but that function only gives you another real as the mantissa. I need an integral mantissa, exponent, and base. Is there either (1) a crafty, cross-platform way of doing this or (2) a function in a standard library that does this that I somehow missed? If there is no such function, what are your thoughts on me implementing such a thing and submitting it to Phobos, probably similar to how frexp is implemented (elseifs for each FP format)? The various functions in std.math mostly extract these values on their own, using the floatTraits template to help. The mach library has the module mach.math.floats.extract: https://github.com/pineapplemachine/mach.d/tree/master/mach/math/floats
Re: Moonshot: a DMD fork that outputs Lua
On Tuesday, 21 February 2017 at 12:45:47 UTC, Mithun Hunsur wrote: Hi all, I've been working on a little project over the last month and a half, inspired by Adam's dtojs (https://github.com/adamdruppe/dtojs). I've always wanted a typed, powerful, embeddable scripting language, but found the contenders lacking - which is why I decided to hack up DMD to emit Lua. This is awesome. Great work! Is there an easy way to see compiler output for some example programs? I encourage you to submit a dconf talk - I know I'd like to hear more about this - just mind that the submission deadline is coming up in a few days.
Re: Enough D to Make a Living?
On Tuesday, 21 February 2017 at 18:32:22 UTC, Nick Sabalausky (Abscissa) wrote: On 02/21/2017 10:34 AM, Paul wrote: 3) Is there much value in taking programming classes that don't deal with D? Although HR folk never understand this, programming skills are highly transferable across languages. So yes, it's definitely worthwhile: Getting better with one language will help you be a better programmer in other languages. Very much this. Companies are never impressed by my knowing any language in particular, they're impressed by the fact I've written code in so many different languages. Statically-typed languages, dynamic languages, scripting languages, JVM languages, assembly languages, etc. etc. etc. Definitely let yourself spend the most time on a language or two you enjoy most, because it's still important to demonstrate that you're able to know a language front-to-back. But experiment with as many other languages as you can, as much as you feel comfortable and then some, because that's how you gradually get to a place where the only thing separating you from proficiency with any programming language is a week or two of ramp-up time. And that alone makes you employable almost anywhere. As for employability: These days, one of the absolute best things you can do is to have an active github account. Put your projects in public repositories, even the small ones, and any time you think of something interesting or you need a tool for yourself, commit code to the site while you're developing it. And never be afraid to submit PRs for improving other people's repos, because it's almost always welcome and it also looks great in terms of employability because it shows how comfortable you are working with other people's code. The overwhelming majority of jobs these days involve writing C++, C#, Java, JavaScript, or Python. You will have a much easier time finding a job writing code mainly in one of those languages than one writing code in D - but that doesn't make learning D useless, or anything close to it. Everything you learn by writing D will be transferable to those other languages, especially C++. Just stay aware that it is well worth your time to familiarize yourself with other languages, too, and be open to the possibility of finding work that focuses on other languages.
Re: Array start index
One reason for zero-based indexes that isn't "it's what we're all used to" is that if you used one-based indexes, you would be able to represent one fewer index than zero-based, since one of the representable values - zero - could no longer be used to represent any index. Also, it's what we're all used to, and it makes perfect sense to a lot of us, and the only times in recent memory I've ever made off-by-one errors were when I was trying to use Lua and its one-based indexing.
Thoughts about exception reporting
Something I keep going back and forth on is the best way to handle exception reporting in different contexts. There are so many idioms to use here and none of them feel quite ideal. I'm not sure the best way to improve it, but I'm hoping a discussion might produce some useful ideas. Some suggestions, apart from the obvious "exceptions shouldn't require the gc": - nothrow might be repurposed to mean "doesn't throw recoverable exceptions", and it not forbid throwing objects that inherit from Error. It's limiting to have to use asserts to report nonrecoverable errors in nothrow code, rather than specialized error classes that might provide better information as to what went wrong. - pure might no longer prevent code from throwing `static const` objects, so that error reporting can still be done using @nogc and user-defined error classes in pure functions. It's unintuitive that asserts and `throw new WhateverError` should be allowed, but not `static const error = new WhateverError; throw error`.
Re: Yield from function?
On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis wrote: I need to yield from a complex recursive function too allow visualizing what it is doing. e.g., if it is a tree searching algorithm, I'd like to yield for each node so that the current state can be shown visually. I realize that there are several ways to do this but D a yield version without additional threads would be optimal. I don't need concurrency or speed, just simple. You may be able to use Generator in std.concurrency for this: https://dlang.org/phobos/std_concurrency.html#.Generator You could also rephrase your algorithm as a range, which would not involve concurrency but may be unintuitive to implement. In this case you would likely have to use a stack or queue rather than a recursive function. Is it an option to just accumulate the information regarding your algorithm in a separate data structure and then analyze it after the algorithm is complete, or has recorded some number of entries?
Re: CTFE Status
On Sunday, 29 January 2017 at 02:52:51 UTC, Stefan Koch wrote: Yes exactly that. many times in phobos foreach(dchar ch; some_string) which requires me to encode the utf8 string temporarily into utf32 and then when it is appending to some other string I need to reencode it into utf8. Oooh, I never realized foreach acted specially like that. I can't decide whether I approve or disapprove. You'll also have to support UTF-16 for the case `foreach(wchar ch; some_string){}`. As before just let me know if I can help.
Re: CTFE Status
On Sunday, 29 January 2017 at 02:17:12 UTC, Stefan Koch wrote: Also my ctfe engine still requires utf8 support, for string-foreach. Currently there are methods for that in druntime, I hope to simply call them at ctfe, rather then re-implement them. If someone volunteers I can provide help to make them ctfeable, however at the moment my free mental bandwidth is too low to deal with utf details. This approach will require the druntime-source containing the utf8 methods to be present and visible at every compiler run that uses string foreach. If you consider this an issue please state why. 1: I think it's good to avoid this if possible, though I'm not fiercely opposed 2: I wrote this for mach: https://github.com/pineapplemachine/mach.d/tree/master/mach/text/utf If you want to borrow code or if I can provide an implementation meeting different requirements then I am at your disposal. 3: Can you clarify what string-foreach refers to? Surely not `foreach(ch; some_string){}`, which enumerates code units and not code points?
Re: Release D 2.073.0
On Saturday, 28 January 2017 at 03:40:43 UTC, Walter Bright wrote: If you've got a case, make it. If you see problems, explain. If you want to help, please do. So, do what numerous people have done numerous times already, to no great effect?
Re: Allow static methods and fields for enum?
On Thursday, 26 January 2017 at 06:40:59 UTC, drug wrote: 26.01.2017 09:32, Profile Anaysis пишет: Why not make enum a comparable type to structs and classes? They are static so they can't contain any mutable fields but surely they can contain methods? And especially they should be able to contain static methods!? What prevents you from using UFCS with enum members or templates with enum itself? (not tested) This is one solution, but it would still be useful as an organizational tool to be able to put those methods in the enum's own namespace.
Re: Learning resources
On Tuesday, 24 January 2017 at 20:15:38 UTC, Dlearner wrote: Hey all! I'm learning programming through D and having a really good time (much better than with C++ or Python). I'm aiming to make little games with it as a hobby so I've learned some OpenGL stuff. But, I feel like I'm learning more library code rather than D concepts and idioms, especially where efficiency and performance are concerned. (I also have a light interest in functional programming for when it would make sense to employ those principles.) Are there any tutorials that show off the power of D with worked examples that explain the importance of certain features? I highly recommend going through this to start with: https://p0nce.github.io/d-idioms/ I've been working on this library (which includes some gamedev and functional programming stuff). It's moderately-well documented and I am more than happy to help and provide examples if it interests you https://github.com/pineapplemachine/mach.d/tree/master/mach/sdl
Re: Multiple return type or callback function
On Monday, 23 January 2017 at 15:15:35 UTC, aberba wrote: I'm creating a function to authenticate user login. I want to determine login failure (Boolean) and error message (will be sent to frontend) but D does have multiple return type (IMO could use struct but will make code dirty with too much custom types). struct Result { bool success = false string message; } Result authen(){} auto r = authen() if (r.success) writeln(r.message); I use structs like this quite frequently, myself. It works well and I don't think it's particularly ugly. And if you don't want to pollute the namespace with one-off structs, you can also place them inside the function that's returning them (making them voledmort types).
Re: Less-than-optimal decimal real literal conversion to x86 extended floats
On Sunday, 22 January 2017 at 01:54:59 UTC, pineapple wrote: When you write `real x = 0.0005;` x in fact represets a value of about 0.00050032187251995663412884596255025826394. This is a about 3.2 * 10^-23 more than 0.0005. The output of my function in this case was about 0.00049979247692792269641692826098733348771. This is a about 2.1 * 10^-23 less than 0.0005. I might have added, for clarity, that there are no representable values in between these two, 0.0005 or otherwise.
Less-than-optimal decimal real literal conversion to x86 extended floats
I'm not sure whether this should be counted as a bug, but I ran into it and thought it deserved mentioning. I've been testing this with DMD on Windows. I wrote this function to support parsing of strings as floating point values: https://github.com/pineapplemachine/mach.d/blob/master/mach/math/floats/inject.d#L28 It is a direct copy of the relevant parts of strtod as implemented here: https://opensource.apple.com/source/tcl/tcl-10/tcl/compat/strtod.c When writing tests for this code I assumed that the result of expressions like `float x = some_literal` would be at least as accurate as the values returned by my code, and so I wrote tests which asserted that the literals and outputted values should be exactly equal. Take for example 0.0005, which is the input that caused me quite a lot of trouble. When producing floats and doubles, the literals and the function outputs are exactly equal, e.g. `myfunc!double(5, -4) == 5e-4`. This is not the case for reals. When you write `real x = 0.0005;` x in fact represets a value of about 0.00050032187251995663412884596255025826394. This is a about 3.2 * 10^-23 more than 0.0005. The output of my function in this case was about 0.00049979247692792269641692826098733348771. This is a about 2.1 * 10^-23 less than 0.0005. In this case, at least, the output of the function I wrote produced a more accurate value than the compiler did. Would it be possible and/or desirable to make DMD use a more accurate string-to-float algorithm?
Re: Profiling calls to small functions
On Saturday, 21 January 2017 at 12:33:57 UTC, albert-j wrote: Now I dmd -profile it and look at the performance of funcA with d-profile-viewer. Inside funcA, only 20% of time is spend in funcB, but the rest 80% is self-time of funcA. How is it possible, when funcB has three times the calculations of funcA? It appears that the call to funcB itself is very expensive. I'm not sure if it's what happening in this case but, in code as simple as this, function calls can sometimes be the bottleneck. You should see how compiling with/without -O affects performance, and adding `pragma(inline)` to funcB.
Re: Assigning in constructor.
On Wednesday, 18 January 2017 at 23:08:07 UTC, Adam D. Ruppe wrote: On Wednesday, 18 January 2017 at 22:57:22 UTC, NotSpooky wrote: Is it undefined behavior to assign to a pointer in the constructor of a struct? Yes: http://dlang.org/spec/struct.html "A struct is defined to not have an identity; that is, the implementation is free to make bit copies of the struct as convenient." That means it might copy and/or move it without giving you a chance to update the pointer. Updating in postblit can help sometimes but still the compiler and library are allowed to move structs without notice. Practically speaking I've found that if the struct was allocated on the heap, then acquires that pointer and seems not to break anything, e.g. how it's used in the uncopyable struct here https://github.com/pineapplemachine/mach.d/blob/master/mach/collect/linkedlist.d#L165
Re: Where is floating point next{Up,Down}?
On Tuesday, 17 January 2017 at 23:41:27 UTC, Nordlöw wrote: On Tuesday, 17 January 2017 at 23:38:46 UTC, Ali Çehreli wrote: Found'em! :) https://dlang.org/phobos/std_math.html#.nextUp Thanks! (Shouts into the soundless void) https://github.com/pineapplemachine/mach.d/blob/master/mach/math/floats/neighbors.d
Re: Printing a floats in maximum precision
On Wednesday, 18 January 2017 at 00:09:42 UTC, Nordlöw wrote: What's the easiest way to print a double in maximum precision? https://github.com/pineapplemachine/mach.d/blob/master/mach/text/numeric/floats.d#L60 You can also try the formatting directive "%.20f" but unlike the former I can't offer any guarantees of its accuracy (it's probably accurate)
Re: Initializing floating point types with explicit mantisa and exponent
On Tuesday, 17 January 2017 at 00:08:24 UTC, Nordlöw wrote: How do I best initialize a D double to an exact mantissa and exponent representation? I'm specifically interested in 2^^i for all i in [min_exp, max_exp] This mach module can do the job: https://github.com/pineapplemachine/mach.d/blob/master/mach/math/floats/inject.d
Re: Quine using strings?
On Monday, 16 January 2017 at 09:33:23 UTC, Nestor wrote: PS. Isn't this approach considered "cheating" in quines? ;) I'm afraid so - while the empty program has been technically accepted as being a quine (e.g. http://www.ioccc.org/1994/smr.hint) programs which use file io to read their own source have not.
Re: Quine using strings?
On Sunday, 15 January 2017 at 21:37:53 UTC, Nestor wrote: Any ideas for a shorter version (preferably without using pointers)? When compiling with the -main flag, this D program is a quine:
Re: What about an identifier that is an mixin
On Friday, 13 January 2017 at 21:15:32 UTC, André Puel wrote: I think this could be useful when one is creating Idiom and Patterns, you could hide implementations details. I'm not sure that this is the kind of implementation detail that ought to be hidden
Re: Seemingly patternless optlink premature termination
On Monday, 9 January 2017 at 02:34:31 UTC, Jerry wrote: before I switched away from optlink. What point is there to report these bugs though, Microsoft's linker works with fewer bugs and actually supports the format of the platform. So no need to convert .lib files with it. This is my point, it's just one more thing that has to be maintained, but it's not even being maintained. Supporting MinGW would be a better option as then you don't have to maintain the linker and not have it degrade over time. On this subject, I spent a good chunk of my day trying to compile my code using the -m32mscoff switch and was never able to get it to work. (My most recent obstacle is this error, occurring even for a very simple test program importing no dependencies, if anyone cares to take a look: https://hastebin.com/vezojehaxo.txt) On Monday, 9 January 2017 at 01:27:27 UTC, Walter Bright wrote: On 1/8/2017 12:58 PM, pineapple wrote: On Sunday, 8 January 2017 at 18:49:50 UTC, Walter Bright wrote: Please post bug reports to bugzilla. Here you go: https://issues.dlang.org/show_bug.cgi?id=17077 Thank you. Regarding the above: Because I have not managed to get an alternative to optlink working, I currently am unable to work on mach on my Windows desktop. In order to keep up progress I've been having to write and compile code on OSX on a laptop; it is nowhere near an ideal workflow. I understand you likely have a lot on your plate, but please prioritize solving this problem. It's causing me a great deal of irritation and inconvenience, and it's embarrassing that my library now simply won't compile on Windows.
Re: Seemingly patternless optlink premature termination
On Sunday, 8 January 2017 at 18:49:50 UTC, Walter Bright wrote: Please post bug reports to bugzilla. Here you go: https://issues.dlang.org/show_bug.cgi?id=17077
Re: Seemingly patternless optlink premature termination
On Sunday, 8 January 2017 at 14:42:57 UTC, pineapple wrote: After deciding to let my inability to add some unit tests to that module I started working on some other code in the same project. At this point it seems completely arbitrary which lines produce optlink errors. Since the `unittest{}` issue I have, in other modules, had optlink errors occur depending on the presence of arbitrary method and function calls, too. Update from IRC: Stefan was able to determine that this is a stack corruption bug with optlink. (How and why I should be the one to stumble upon it is yet to be determined.)
Re: Seemingly patternless optlink premature termination
On Sunday, 8 January 2017 at 14:15:26 UTC, pineapple wrote: I'm working on my dumb library and I have run into a case where when I add this line to a module, I get an optlink error attempting to compile it: unittest{} After deciding to let my inability to add some unit tests to that module I started working on some other code in the same project. At this point it seems completely arbitrary which lines produce optlink errors. Since the `unittest{}` issue I have, in other modules, had optlink errors occur depending on the presence of arbitrary method and function calls, too.
Seemingly patternless optlink premature termination
I'm working on my dumb library and I have run into a case where when I add this line to a module, I get an optlink error attempting to compile it: unittest{} The module compiles fine without it. So do the modules which depend on it. But with that line? optlink errors everywhere. A screencap of the error box that pops up: http://puu.sh/tfmBK/c5068eb2fb.png And the contents of stdout: checkpoint(256) --- errorlevel 1 I encountered a similar error right before this and eventually worked out that I had introduced a cyclic dependency into my project some time ago - strangely not rearing its head as an error until I made a completely unrelated addition to the tests in a module incidentally importing one of the modules involved in that dependency cycle - and addressing that issue seemed to resolve the optlink error. (At least until I tried to add some extra unit tests to one of the modules involved in that cycle.) I am utterly failing to find a way to make a simple repro case from this, or to understand what could conceivably be causing this error to occur in a module whose dependency graph is small and simple.
Re: To use a scripting language or not to use a scripting language?
On Friday, 6 January 2017 at 09:54:32 UTC, Dmitry wrote: On Thursday, 5 January 2017 at 22:37:21 UTC, solidstate1991 wrote: I'm thinking on possibly implementing a scripting language for my game engine for general purpose and AI. At one point I was thinking on making a scripting language based on D with ECMAScript and Prolog/Planner influences. As a game developer I can recommend to use Lua. This language is tradtionally used in many games/game engines. Thirded. Lua is relatively easy to implement support for, is not too bad a language, and a lot of people are already familiar with it.
Re: Parsing a UTF-16LE file line by line, BUG?
On Friday, 6 January 2017 at 06:24:12 UTC, rumbu wrote: I'm not sure if this works quite as intended, but I was at least able to produce a UTF-16 decode error rather than a UTF-8 decode error by setting the file orientation before reading it. import std.stdio; import core.stdc.wchar_ : fwide; void main(){ auto file = File("UTF-16LE encoded file.txt"); fwide(file.getFP(), 1); foreach(line; file.byLine){ writeln(file.readln); } } fwide is not implemented in Windows: https://msdn.microsoft.com/en-us/library/aa985619.aspx That's odd. It was on Windows 7 64-bit that I put together and tested that example, and calling fwide definitely had an effect on program behavior.
Re: Parsing a UTF-16LE file line by line, BUG?
On Wednesday, 4 January 2017 at 19:20:31 UTC, Nestor wrote: On Wednesday, 4 January 2017 at 18:48:59 UTC, Daniel Kozák wrote: Ok, I've done some testing and you are right byLine is broken, so please fill a bug A bug? I was under the impression that this function was *intended* to work only with UTF-8 encoded files. I'm not sure if this works quite as intended, but I was at least able to produce a UTF-16 decode error rather than a UTF-8 decode error by setting the file orientation before reading it. import std.stdio; import core.stdc.wchar_ : fwide; void main(){ auto file = File("UTF-16LE encoded file.txt"); fwide(file.getFP(), 1); foreach(line; file.byLine){ writeln(file.readln); } }
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Saturday, 31 December 2016 at 17:02:55 UTC, Chris Wright wrote: This extension removes an unforced limitation of the current with syntax (allows it to occur at top level) In other words, another aspect of this DIP is that I can write: module foo; static import std.traits; static import bar; with (std.traits) { template Foo(T) if (isAbstractClass!T) {} } with (bar.SomeEnum) { enum something = SomeEnumValue; } This is the only expression of the feature I've seen so far that makes intuitive sense to me. I'm still not sold on it being a worthy addition but, if it were, then this is the most promising syntax I've seen so far.
Re: Working with Modules
On Wednesday, 28 December 2016 at 02:08:44 UTC, Guy Asking a Question wrote: import test; <---dmd choking here. You will need to use the -I option of dmd/rdmd to inform the compiler of where your `HopefullySomeDLibrary` directory is located, as well as any other places you will want to import modules from. If you're using another compiler, it should have a similar option. (Though I can't speak from experience.)
Re: It's a Christmas miracle: main no longer runs after unittests
On Saturday, 24 December 2016 at 22:14:08 UTC, Andrei Alexandrescu wrote: https://github.com/dlang/druntime/pull/1724 Ho-ho-ho! Andrei Unacceptable. All breaking changes (Except the ones I create) are evil.
Re: Multiple return value as requirements for safety and performance
On Tuesday, 20 December 2016 at 15:42:52 UTC, Ilya Yaroshenko wrote: This thread is about mutiple values returned by _reference_. Tuples can not do it, only pointers, but they are not ctfeable and safe The way to make this useful, if I'm understanding correctly, would not be a more concise way to express `return tuple(a, b);` where `tuple` is the function defined in typecons, but to make expressions like `return tuple(a, b).expand;` become valid and using a syntax like `return (a, b);` to represent them. (For which I would suggest also making the parentheses optional, but that's minutiae.) The syntax for assigning the returned values would likely not look like `auto x = {return (a, b);}(); assert(x[0] == a);`. This because `x` would not be a tuple in the sense of std.typecons.Tuple, but a tuple in the sense of what you get when you `expand` such a type. The assignment syntax should be more like `auto x, y = {return (a, b);}(); assert(x == a);`. Where the intent is to store the two values in the same variable, I expect a struct like Tuple should continue to be used. And because in these examples `a` and `b` would not be members of a tuple struct, it would become possible to return some or all of them by reference, as can currently be done for a single returned value.
Re: sort, .array and folding on immutable data (finding most common character in column of matrix)
On Monday, 19 December 2016 at 09:24:38 UTC, Ali wrote: Ok so laziness stops as soon as sort is required on a range then? Ahh, because in place algorithms? Are there any plans in D to make is to that you can output copies to collections so that you could do something like filter.transpose.sort and just have it output a modified copy? This is a shortcoming of Phobos - here is a package of sorting algorithms including some that do not require their inputs to be mutable, random access, and/or finite: https://github.com/pineapplemachine/mach.d/tree/master/mach/range/sort The library is permissively licensed; feel free to take out whatever you need. It's worth noting that giving up eagerness, random access, etc. often comes with a speed penalty. It may be more efficient just to copy the lazy things into memory first and then sort in-place, as you have been doing.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Monday, 19 December 2016 at 00:54:13 UTC, Andrei Alexandrescu wrote: On 12/18/16 7:44 PM, pineapple wrote: On Sunday, 18 December 2016 at 23:18:27 UTC, Andrei Alexandrescu wrote: Great, thanks. Please take a look at the accuracy of the discussion. I expanded the "Workaround" section and moved it near the top. I would also like to register that while I respect your argument regarding scalability, I have personally found that a greater number of smaller files is easier to manage than a smaller number of larger files. Including for the 580,000+ line project I work on for a living. Is it publicly available? -- Andrei Sadly not.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Monday, 19 December 2016 at 00:44:14 UTC, pineapple wrote: On Sunday, 18 December 2016 at 23:18:27 UTC, Andrei Alexandrescu wrote: Great, thanks. Please take a look at the accuracy of the discussion. I expanded the "Workaround" section and moved it near the top. I would also like to register that while I respect your argument regarding scalability, I have personally found that a greater number of smaller files is easier to manage than a smaller number of larger files. Including for the 580,000+ line project I work on for a living. (Granted, that old ugly codebase has a lot of problems of its own, and smaller files does not always mean small on the same scale that mach.d's files are small, but I can tell you from experience that once a single ~4,000 line module was broken down into many ~200 line modules, that code became a great deal easier to understand and to reason about and to maintain.)
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 23:18:27 UTC, Andrei Alexandrescu wrote: Great, thanks. Please take a look at the accuracy of the discussion. I expanded the "Workaround" section and moved it near the top. I would also like to register that while I respect your argument regarding scalability, I have personally found that a greater number of smaller files is easier to manage than a smaller number of larger files. Including for the 580,000+ line project I work on for a living.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 23:18:27 UTC, Andrei Alexandrescu wrote: Great, thanks. Please take a look at the accuracy of the discussion. I expanded the "Workaround" section and moved it near the top. https://github.com/dlang/DIPs/pull/51 https://github.com/dlang/DIPs/blob/dd46252e820dce66df746540d7ab94e0b00a6505/DIPs/DIP1005.md Andrei It's reasonably accurate. The only thing I would point out is that few modules define only one public symbol; the median probably lies around 4 or 5. A few modules, most or all being in the traits package, define considerably more. The mach.traits.primitives module defines 28 public symbols, by my count. (Though that's still small stuff relative to Phobos.) I think it would be most accurate to word the sentence as: It is organized as such that each module contains a small number of related declarations (such as canAdjoin, Adjoin, and AdjoinFlat in module adjoin.d) along with documentation and unit tests.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 22:31:34 UTC, Andrei Alexandrescu wrote: Is there a simple command to e.g. unittest everything in the project? Also, is there a build process or it's all templated? -- Andrei There's no build process. To run tests, I compile the root `package.d` file with rdmd, including the -debug, -unittest, and --main flags, and -I"path/to/repo/mach.d". To compile the mach.sdl package, which is not currently imported by the root `package.d`, you would have to include a directory containing the requisite Derelict dependencies for the -I option.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 21:09:46 UTC, Andrei Alexandrescu wrote: On 12/18/2016 10:01 AM, pineapple wrote: On Sunday, 18 December 2016 at 13:31:48 UTC, Andrei Alexandrescu wrote: Is the source code publicly available? https://github.com/pineapplemachine/mach.d The code looks clean, congrats. With your permission I'd like to give this library as an example in the "Workaround: Increasing Granularity of Modules" section. Please advise, thanks. -- Andrei No problem, feel free. Thank you for asking.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 13:31:48 UTC, Andrei Alexandrescu wrote: On 12/17/16 10:21 PM, pineapple wrote: I am developing a general-use library for D that is currently resting at around 50,000 lines. Is the source code publicly available? https://github.com/pineapplemachine/mach.d
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Sunday, 18 December 2016 at 02:40:59 UTC, Chris Wright wrote: D doesn't have either of those pitfalls, so I haven't seen it cause problems. I'm also a bit skeptical that this will see much use outside phobos. This isn't really an argument against it. I just don't see any argument for it, not that's supported by my own experience. I would like to echo this sentiment. I am developing a general-use library for D that is currently resting at around 50,000 lines. I have never felt a need for a feature like this, and I can't imagine a reason to begin using it. Dependency management has just never presented an issue. Very nearly all modules in the library are fewer than 1,000 lines long and very nearly all symbols are selectively imported, and the approach has proven to be completely manageable. If it can be added without interfering with the existing patterns, I don't really have an argument against this feature. But I do think that what this DIP is meant to address is not really a problem experienced by all or even most who are working with D. It's a problem being experienced with Phobos, but there are very valid solutions to that problem that don't involve an addition to the language - only some refactoring. I think that makes the argument in favor somewhat weak.
Re: DIP10005: Dependency-Carrying Declarations is now available for community feedback
On Wednesday, 14 December 2016 at 01:53:44 UTC, Chris M. wrote: How about using "imports" instead of "import"? Simple enough change, and it still makes sense bool equal(R1, R2) imports (std.range) if (isInputRange!R1 && isInputRange!R2) { ... } On Tuesday, 13 December 2016 at 23:03:39 UTC, Timon Gehr wrote: I'd prefer syntax like (import foo.bar).baz and (import foo).bar.baz. (I.e., the syntax of import expressions would closely mirror that of import declarations, and would be unambiguous.) 2. The behaviour of aliases to import expressions should be defined explicitly. I.e. alias short = import very.long.module_name; void foo(int i)(short.T a){ ... } does this import the module if foo is not instantiated? I am most in favor of making the function signature either `imports` or `@imports`, or doing this: struct Buffer(R) if (import std.range:isInputRange!R) { ... } I also think actually being able to write `alias short = import very.long.module_name;` would be great, if only so that the contents of a module can be imported into their own user-defined namespace rather than the global scope.
Re: wrong isInputRange design
On Sunday, 4 December 2016 at 11:18:56 UTC, rumbu wrote: Yes, this is the same workaround I found, but that does not solve the fact that the following code does not compile: While it may be too late to redeem Phobos and its handling of arrays as ranges, it is worth noting that in the library I've been working on the `isRange` template behaves like you're expecting. In mach, `front` and `popFront` and `empty` are not defined for strings; rather, functions that accept ranges also accept types that ranges can be made to enumerate, including strings and other arrays. If you really wanted an `isInputRange` that behaves like you're wanting, it's only a 6 line template that you would have to interject in your code. enum bool isInputRange(T) = is(typeof({ T range = T.init; if(range.empty){} auto element = range.front; range.popFront(); })); https://github.com/pineapplemachine/mach.d
Re: Formal review of DIP1002
On Thursday, 17 November 2016 at 11:37:09 UTC, Dicebot wrote: Disposition: REJECT. A proposal for a similar or identical feature would need to be include qualitatively new motivation/evidence of usefulness. Please follow the link for the full review text / rationale: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1002.md#review There should be no need for me to repeat the arguments against the DIP process already made by others. I will be submitting no more DIPs or engaging in the process in any way unless and until it is significantly changed.
Re: problem with isnan
On Thursday, 10 November 2016 at 16:47:30 UTC, Adam D. Ruppe wrote: On Thursday, 10 November 2016 at 16:41:56 UTC, Charles Hixson wrote: It's *supposed* to be nan, and the assert message reports that it is, but it should pass the assert test, not throw an assertion. What am I doing wrong? How did you set it? There are like billions of different NaNs. I'm not sure if isnan checks for all of them. (I'm also not sure that it doesn't, the docs don't specify.) you might try using std.math.isNaN instead and see what it does. Incidentally, I just recently submitted a PR to fix this. What probably happened is that you're referring to a limited `isnan` method defined as a unittest utility method in object.d that should have been private but wasn't. You want to use `isNan` instead.
Re: Best way to get ceil(log2(x)) of a BigInt?
On Wednesday, 2 November 2016 at 14:24:42 UTC, Andrea Fontana wrote: On Wednesday, 2 November 2016 at 14:05:50 UTC, pineapple wrote: I'm trying to do some math stuff with std.bigint and realized there's no obvious way to calculate the ceil of log2 of a bigint. Help? How big are your bigints? I think they'll generally stay between 0 and 2^200 I came up with this, I guess it'll work? auto clog2(BigInt number) in{ assert(number > 0); }body{ uint log; auto n = number - 1; while(n > 0){ log++; n >>= 1; } return log; }
Best way to get ceil(log2(x)) of a BigInt?
I'm trying to do some math stuff with std.bigint and realized there's no obvious way to calculate the ceil of log2 of a bigint. Help?
Re: A question of function design?
On Thursday, 27 October 2016 at 22:17:35 UTC, WhatMeWorry wrote: I'm using Derelict GLFW3 and I found the following GLFW3 code snippet in a demo. In a small demo, crap like this usually isn't a big deal. It's not common practice, though, and for good reason. You should definitely avoid imitating it.
Re: Can we get unitests to not run with program start ?
On Wednesday, 26 October 2016 at 08:15:44 UTC, Basile B. wrote: What would be possible is a "-fdmain" switch (force dummy main). Its role would be: if a functionDeclaration named "main" is present then this normal "main" is not used (technically erased from the AST or something like that). Then acts like "-main". Just using `-main` has worked well enough for me
Re: Working with ranges: mismatched function return type inference
On Tuesday, 11 October 2016 at 07:55:36 UTC, orip wrote: I get "Error: mismatched function return type inference" errors with choosing the return type for functions that work on ranges using, e.g, std.algorithm or std.range functions, but have different behavior based on runtime values. The return type is always a range with the same underlying type. Here's an example: auto foo(int[] ints) { import std.range; if (ints.length > 10) { return chain(ints[0..5], ints[8..$]); } else { //return ints; // Error: mismatched function return type inference of int[] and Result return chain(ints[0..0], ints[0..$]); // This workaround compiles } } Is there a compatible return type that can be used, or some other workaround? I couldn't find one when searching for the error or looking at the phobos source code. Thanks! orip Rewrite `return chain(ints[0..5], ints[8..$]);` as `return ints[0..5] ~ ints[8..$];` The `chain` function doesn't return an array, it returns a lazily-evaluated sequence of an entirely different type from `int[]`.
Re: Why can't static arrays be sorted?
On Thursday, 6 October 2016 at 09:17:08 UTC, pineapple wrote: On Wednesday, 5 October 2016 at 19:30:01 UTC, Jonathan M Davis wrote: Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem. It doesn't even make conceptual sense for a static array to be a range, because you can't remove elements from it. - Jonathan M Davis Just because the static array itself isn't a range doesn't mean that it should be necessary to do unintuitive gymnastics with it just to pass it to functions like `sort`. I mean, people post here how often asking why static or dynamic arrays aren't being accepted by Phobos' range functions in their code? Maybe Phobos really ought to consider another approach. Accepting things that are _valid_ as ranges and not only things that are ranges themselves has proven to be an effective strategy in mach.
Re: Why can't static arrays be sorted?
On Wednesday, 5 October 2016 at 19:30:01 UTC, Jonathan M Davis wrote: Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem. It doesn't even make conceptual sense for a static array to be a range, because you can't remove elements from it. - Jonathan M Davis Just because the static array itself isn't a range doesn't mean that it should be necessary to do unintuitive gymnastics with it just to pass it to functions like `sort`.
Re: Examples Wanted: Usages of "body" as a Symbol Name
On Thursday, 6 October 2016 at 06:38:06 UTC, Jonathan M Davis wrote: Yeah, the fact that the body keyword is not required normally but is when you have in/out contracts is annoying, completely aside from what the keyword used is. I don't care much about losing the name body to a keyword, but I definitely don't like that you have to use a keyword for a function body when you have in/out contracts. It doesn't seem like it should be necessary, and it's inconsistent with the normal case. - Jonathan M Davis I agree 100%.
Re: Examples Wanted: Usages of "body" as a Symbol Name
On Wednesday, 5 October 2016 at 19:02:02 UTC, Basile B. wrote: On Wednesday, 5 October 2016 at 18:41:02 UTC, Jacob Carlborg wrote: On 2016-10-05 19:14, Matthias Klumpp wrote: Agreed - I have exactly the same problem with "version", which is also really common for, well, to hold a version number of a component. Body is annoying too. But, can keywords actually sanely be removed from the language without breaking the world? In Ruby most keywords are not reserved words. a.`def`() D context free grammar allow fast highlighting. I understand that people who write scripts think that it won't change anything...but it's not the reality. D is a system programming language, people who use D can deal with code base > 60 Kloc. And we don't want to see such a change because you can't use "body" in your student project. In general I don't think this is a problem, but `body` is an unconventional term to have as a keyword. The other keywords that are used for function contracts (`in` and `out`) are also used in other places - perhaps `body` could be deprecated and eventually removed in favor of using another keyword instead? Either another, different keyword that is less likely to collide with common attributes of user types, or an existing keyword not meaningful in the same context. There may also be a case for making `body` implicit - e.g. void func() in{ // }out{ // }body{ // } Would become void func() in{ // }out{ // }{ // } I don't think this is of critical importance, but dealing with this somehow would definitely be a step in the right direction.
Re: Why can't static arrays be sorted?
On Wednesday, 5 October 2016 at 18:19:27 UTC, TheGag96 wrote: On Wednesday, 5 October 2016 at 02:19:13 UTC, Jonathan M Davis wrote: The problem is that static arrays aren't ranges (calling popFront on them can't work, because their length isn't mutable). However, you can slice a static array to get a dynamic array which _is_ a range. e.g. thing[].sort(); Just make sure that such a dynamic array does not outlive the static array, or it will refer to invalid memory (which would not be a problem in this case). - Jonathan M Davis Ah thanks guys. I think I just got used to thinking arrays would always be found to be ranges by the compiler. Good to know! Would just like to point out that this is design weirdness on Phobos' part - the library I've been writing does not have this problem.
Re: How to make rsplit (like in Python) in D
On Monday, 3 October 2016 at 19:25:59 UTC, Uranuz wrote: When I pass empty string to splitter in most of languages I expect to get list with 1 item (empty string) as a result, but I get error instead. And I see inconsistency in that .front behaves normally, but .back is not. Usually I access front of range directly without any check when I expect it to have exactly 1 item. But in this case it not working and is very strange. Hm, if front works but not back that is probably a bug. I think checking whether the range is empty before accessing the member should be a viable workaround.
Re: How to make rsplit (like in Python) in D
On Saturday, 1 October 2016 at 17:55:08 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:32:59 UTC, Uranuz wrote: On Saturday, 1 October 2016 at 17:23:16 UTC, Uranuz wrote: [...] But these example fails. Oops. Looks like a bug( import std.stdio; import std.algorithm; import std.range; import std.string; [...] I created bug report on this: https://issues.dlang.org/show_bug.cgi?id=16569 This isn't a bug. It's illegal to access the front or back of an empty range. (If anything is a bug, it's the nondescriptiveness of the error.) You should write this instead: void main() { string str = ""; auto split = str.splitter('.'); if(!split.empty) writeln(split.back); }
Re: Get date at compile time
On Saturday, 1 October 2016 at 14:43:31 UTC, Adam D. Ruppe wrote: On Saturday, 1 October 2016 at 14:41:22 UTC, Andrew wrote: Is there any way to get the system date at compile time. Not exactly, but the special symbol __TIMESTAMP__ gets a string out of the compiler at build time. http://dlang.org/spec/lex.html#specialtokens Has there been consideration for adding separate integral tokens for day, month, year, etc? The documentation there doesn't seem to specify but I assume currently the timestamps are for local time? Though I don't currently have any need for this feature I'd imagine that if I did I'd want the time in UTC, not locally, or if it was local that I'd at least want to be able to similarly retrieve the timezone info.
Re: Overloading relational operators separately; thoughts?
On Saturday, 1 October 2016 at 07:13:39 UTC, Martin Nowak wrote: The fact that it's not possible to overload < but have to use the ternary opCmp is even a performance problem. All std algorithms only use less as a predicate, leading to lots of unnecessary cycles when e.g. sorting UDTs. On Saturday, 1 October 2016 at 11:53:07 UTC, Andrei Alexandrescu wrote: Apparently in dmd the generated code is less efficient: https://goo.gl/OWxbA0. In gdc it's the same: https://godbolt.org/g/NmUyXM. I couldn't test with ldc, http://ldc.acomirei.ru seems down. -- Andrei On Saturday, 1 October 2016 at 06:46:31 UTC, Russel Winder wrote: This debate is about whether D constrains people as Java does or whether it enables people as C++ and Python do. Or use C++ or Python which allow for this. Fine, end of D having a future amongst a large section of the programming population. This is fine. Unless D wants to be a player in this game. This has already been done, read the thread. SQLAlchemy. The expression language is a a lovely builder DSL for constructing SQL entirely in Python with no parser overhead. No operator overloading, no DSL for builder languages. See same on the JVM: in Java you can't do it, Kotlin, Ceylon, Scala, Groovy, do it beautifully, and a lot of people do. This isn't a PR yet because it's not nearly ready for general consumption, but these are all good points and I'd greatly appreciate if you would all please take a few minutes to express them in the DIP and get the changes merged so that we can have something that lays out clearly the pros and cons of this change. https://github.com/pineapplemachine/DIPs/blob/operator_overload_expansion/DIPs/DIP1003.md
Re: Overloading relational operators separately; thoughts?
On Friday, 30 September 2016 at 22:38:07 UTC, Walter Bright wrote: A more productive way forward is for you (and those who agree with you) to prepare a formal DIP and submit it. It's the way significant language change proposals are done. A good idea. I have written a rough initial draft for this DIP and it currently resides here, in a fork: https://github.com/pineapplemachine/DIPs/blob/operator_overload_expansion/DIPs/DIP1003.md I invite anyone with an opinion - which I imagine is just about everyone who has participated in this thread - to please contribute to the DIP before it's submitted as a PR and for review. I ask that arguments for and against listed in the DIP not include anything to the effect of merely "it would offer more flexibility" or "it would offer too much flexibility", as I think several pages of discussion have made clear that those holding either opinion are not likely to be swayed by arguments taking the opposing form.
Re: Overloading relational operators separately; thoughts?
On Friday, 30 September 2016 at 16:25:45 UTC, Jonathan M Davis wrote: But if you or anyone else wants to do wacky stuff with overloaded operators that is not consistent with the built-in types, you're free to do so within how D's overloaded operators work. You're just not going to be able to do it as freely as you can in C++, because that goes against the goals of the operator overloading feature in D, and some of the improvements that were in line with the goals happen to have gotten in the way of such operator overloading abuse. In your arguments in favor of this limitation of operator overloading, you keep referring to these goals, of what operator overloads have been intended to do. You've stated and restated that same explanation even though it's completely unconvincing because while stating this intention you have failed entirely to justify it. How many people have to state it how many times in how many different ways before it gets through? These are stupid goals. They reflect intention that has no basis in reason, that has no basis in reality, that is a blindly-enforced dogma. It always would have been simpler if, in the first place, opBinary had caught comparison operators and opCmp and opEquals were omitted. Instead, those making the decisions went out of their way to impose these arbitrary limitations. If we can start now to untangle that mistake, it will make D more tenable for real-world code. And make no mistake: Perl is fantastic for real-world code because real-world code is not elegant, and it doesn't follow the rules, and it doesn't care how you meant for a feature to be used. Practical languages give the programmer a great deal of expressive power, and it's okay if the rules allow nonsense expressions because it's up to the programmer, not the language, to know what's nonsense and what's not.
Re: Overloading relational operators separately; thoughts?
On Friday, 30 September 2016 at 00:50:54 UTC, Jonathan M Davis wrote: Except that it kind of is. It's an example of a language allowing you to mess with too much and make it so that it doesn't function as expected, which is what happens when you overload operators to act in a way inconsistent with how they work with the built-in types. Which language is more widely used? D or Perl? Let me see if I understand your argument: We can't make D more expressive because a language far more popular than D is so expressive it makes it possible to do unconventional things, if you are so inclined?
Re: Overloading relational operators separately; thoughts?
On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis wrote: The reality of the matter is that D's operator overloading was designed specifically so that you could overload the built-in operators to be used with your own types so that they could act like the built-in types. It was not intended or designed to allow for the symbols use for those operators to then be used for other arbitrary stuff that's unrelated to what they mean for the built-in types. I repeat: Your thinking like this limits D's viability for real-world code. Yes, I understand, the reason operator overloading works the way it does now is because members of the community wanted to arbitrarily limit programmers working in the language. Because they believed theirs was the singular appropriate way to use the language, to the exclusion of all others. I'm opinionated too, but I also have the presence of mind to recognize that my opinions are not universal, and they are certainly no basis for imposing arbitrary limits upon another person's behavior. On Thursday, 29 September 2016 at 19:39:35 UTC, Jonathan M Davis wrote: And there are plenty of folks who think that overloading operators to do stuff fundamentally different from how they work for the built-in types is bad practice and consider it to be an abuse of operator overloading. So, the fact that D limits that is going to be viewed as positive by many folks. Let me see if I understand your thinking: What you're saying is that because some people may not want to use a feature in a specific way, D should disallow anyone from using the feature in that way? That, somehow, contrary to logic, you believe this contributes positively to D's usability and appeal?
Re: Overloading relational operators separately; thoughts?
On Thursday, 29 September 2016 at 18:38:42 UTC, Jonathan M Davis wrote: You just can't use overloaded operators for it, since it would not be in line with what the operators are supposed to mean and be used for. This is not a valid argument because what an operator is "supposed to mean" is up to the programmer who wishes to implement that operator for their data type. Not up to me. Not up to you. Your thinking like this limits D's viability for real-world code. Programmers do not care how you think they are supposed to use the language. They care only that they can get their job done in a way that makes sense to them. What makes sense to them will not be the same as what makes sense to you. Relinquish the notion that you or anyone can have the slightest idea what any language feature is "supposed to mean and be used for".
Re: DIP Mir1 Draft: Variadic template parameters with the same time.
On Thursday, 29 September 2016 at 18:56:40 UTC, Ilya Yaroshenko wrote: No, it does not --- void foo(size_t[] I...)(I i) { } Using phobos' allSatisfy or a similar template, this can become: enum isIndex(T) = is(T == size_t); void foo(I...)(I i) if(allSatisfy!(isIndex, I)){ ... }
Re: DIP 1002 (TryElseExpression) added to the queue
On Thursday, 29 September 2016 at 11:45:42 UTC, Marc Schütz wrote: On Wednesday, 28 September 2016 at 22:12:27 UTC, Idan Arye wrote: Foo foo; try { foo = Foo(); } catch (FooCreationException) { // ... } else { foo.doSomethingWithFoo(); } // foo exists here - it could be initialized, it could be not... And `Foo` could have `@disabled this()`, so you simply _can't_ declare it without initializing it (or use the dirty `Foo foo = Foo.init` workaround). But of course, that's a corner case... This is actually 100% of why I think scope sharing between `try`, `catch`, `finally`, and `else` statements deserves consideration. `Foo` should not have to be mutable or rebindable in order to handle its success or error state in the other statements. On Thursday, 29 September 2016 at 12:24:31 UTC, Andrei Alexandrescu wrote: Thanks, Jack. Here I'm solely focused on making DIP1002 stronger so I've sent a number of suggestions that I believe would improve the proposal. Although you are free to argue here that in fact the proposal already is strong enough, this is not a "minimal requirements" setup in which a DIP is good to go as long as it passes a checklist. The demand here is elastic; the stronger the DIP, the better. Once submitted, if rejected, the only way to propose a similar feature is by authoring a new proposal with a completely novel perspective. So official review is an important milestone with a high bar. -- Andrei I do appreciate the feedback, by the way, which is why I submitted the recent PR. One thing I'd point out: You rewrote my rewritten examples without using `else`, but as was stated immediately before I listed those examples: The best examples of code that can be more elegantly written using this `else` clause occur in application logic, such as the example described above where a values were read from sensors and saved to a server. However, there are a few places in Phobos that could be more readable and not require success flags if this new syntax were employed.
Re: Overloading relational operators separately; thoughts?
On Thursday, 29 September 2016 at 12:20:42 UTC, Russel Winder wrote: Opinionated is not always bad. Look at Go, the developers know that there is no sane way of doing generics so they ban it. Also they know that exceptions are totally incomprehensible to all programmers so they ban them. Rust developers know that all memory handling must be explicit all the world falls apart. Opinionated languages clearly get traction – not usually because of the opinions, it has to be said, more usually because of the amount of money thrown at marketing. Except Python, obviously. Reminds me of this - https://twitter.com/paniq/status/757951588057096192
Re: DIP 1002 (TryElseExpression) added to the queue
On Thursday, 29 September 2016 at 10:51:01 UTC, Nick Treleaven wrote: Note that finally(bool) is more flexible than finally/else as you can interleave code arbitrarily. __guard makes it clearer something special is happening rather than just implicitly extending `try` scope in the `else` clause. Also, 'else' is not clear enough IMO. While I think finally(bool) is a decent approach, the languages that currently integrate this concept into their error handling - Python and Ruby to my knowledge - all use `else`. Clarity is not a good argument, because those who are already proficient in languages other than D will expect the syntax to be consistent with other languages. It would be like some language using foolishly using `elsif instead of `else if`. (Dammit, Perl.)
Re: Overloading relational operators separately; thoughts?
On Thursday, 29 September 2016 at 07:58:26 UTC, Walter Bright wrote: On 9/28/2016 11:48 PM, Jacob Carlborg wrote: If that is not allowed, why is this allowed: I.e. you can overload '+' to do bad things. Yes, you can, and as I replied upthread that can be done because there's no way to prevent that while having operator overloading at all. But that is not justification for allowing such disasters for the comparison operators. I.e. one weakness is not justification for opening the door to all weakness. Interestingly, by shutting the door on misuse of the comparison operators, it seems D has been successful in discouraging nutburger designs like overloading '+' to mean 'OR'. The language you just provide a set of tools, then it's up the to the programmer to do what he/she wants to do. That can be used to justify any feature at all. This is not an argument to justify adding just any feature, it's an argument that it is idiocy to give a programmer a powerful tool, and then impose arbitrary limitations upon how they are allowed to use it. One of the most popular topics of discussion in this forum is "Why is D not more widely adopted?" and "What can we do to get broader adoption for D?" Perhaps one of the more obvious answers is: Do not prevent programmers from doing something solely on the basis that _you_ would not want to do it. I think camelCase is hideous, but does that mean I should forbid another programmer defining symbols in that style? Of course not. That they are able to write their code that way doesn't mean I have to, and doesn't mean I have to use or interface with their code. I agree that '+' should always mean addition and '~' should always mean concatenation, but does that mean I should forbid another programmer from defining them differently? Of course not. Just because they are able to do it that way doesn't mean I have to, or that I have to use their code. If I thought '>' and '<' should always mean arithmetic comparison, does that mean I should forbid another programmer from defining them differently? You need to understand that _you are not the only one writing code in this language_. Your use cases do not summarize all possible use cases. That you do not need to use a tool in a specific way is not a valid argument against allowing others to use the tool that way. Give us a rational argument. We are unconcerned with your personal dogma. What you refer to as a weakness I view as a strength. Programmers require more flexibility and expressiveness, not less.
Re: Overloading relational operators separately; thoughts?
On Wednesday, 28 September 2016 at 20:16:08 UTC, Walter Bright wrote: Because there is no way to stop the former but still have operator overloading. To reiterate, operator overloading exists in D to support the inclusion of arithmetic library types. Any other purpose is discouraged, and that includes expression templates and things like << for iostreams. This is an obsolete way of thinking about operators. Operator overloading exists to make the programmer's life easier, and limiting the ways in which a valuable tool can be used drives people to languages which allow them to be more expressive. For my job I write Python. We use a database layer called sqlalchemy that allows us to express queries by writing, for example, `session.query(some_table).filter(row1 == row2)` and I cannot begin to express how useful this is when writing code, when maintaining code, and when attempting to understand code that someone else wrote. The objective should never be to stop the programmer from doing something because you personally dislike the practice.
Re: Parameterized delegate attributes
On Wednesday, 28 September 2016 at 17:00:49 UTC, Lodovico Giaretta wrote: but a good compiler should be able to recognize functions with the same code and fold them; for example, if a function takes a generic pointer, chances are it doesn't need to be duplicated for every pointer type. But using a templated opApply currently breaks type inference in `foreach`, right? It'd be really nice if that were fixed.
Re: DIP 1002 (TryElseExpression) added to the queue
On Wednesday, 28 September 2016 at 20:18:06 UTC, pineapple wrote: This is not and was not intended to be a glorious, incredible addition to the language. It is meant to shove D a couple inches further in the direction of modern programming constructs. Everywhere a programmer can use `else` instead of mucking about with a boolean success flag and having to make absolutely sure the code intended to handle a success state doesn't and will never be modified to throw an exception that the error handling code isn't designed for means less time spent on tedium, and less opportunity for programmer error. Or, more concisely: Just because we have `for` doesn't mean we reject `foreach`. Just because we have `while` doesn't mean we reject `for`. Just because we have `goto` doesn't mean we reject `while`.
Re: DIP 1002 (TryElseExpression) added to the queue
On Wednesday, 28 September 2016 at 17:56:13 UTC, Steven Schveighoffer wrote: The more I think about this submission, I feel like the benefits are quite slim. This is not and was not intended to be a glorious, incredible addition to the language. It is meant to shove D a couple inches further in the direction of modern programming constructs. Everywhere a programmer can use `else` instead of mucking about with a boolean success flag and having to make absolutely sure the code intended to handle a success state doesn't and will never be modified to throw an exception that the error handling code isn't designed for means less time spent on tedium, and less opportunity for programmer error. On Wednesday, 28 September 2016 at 17:56:13 UTC, Steven Schveighoffer wrote: For example, should it be valid to use "else" without a catch? Yes. On Wednesday, 28 September 2016 at 17:56:13 UTC, Steven Schveighoffer wrote: The boolean to indicate an exception was thrown is cumbersome, but not horrible. Having the compiler manage the boolean may make this cleaner (e.g. finally(bool thrown)), I like it better than the else suggestion. I think this would be an improvement over the current exception handling, but `else` is a pre-existing concept and making `finally` optionally accept a boolean this way tosses convention on its head, and not in a way I think is desireable. If what you're looking for is a clean solution, `finally(bool)` is definitely not it. Moreover, Idan's suggestions about scope sharing make sense to me and I don't think his line of thinking would be compatible with doing it the way you suggest.
Re: DIP 1002 (TryElseExpression) added to the queue
I submitted a PR addressing some of the mentioned criticisms: https://github.com/dlang/DIPs/pull/46
Re: DIP 1002 (TryElseExpression) added to the queue
On Wednesday, 28 September 2016 at 07:47:32 UTC, Andrei Alexandrescu wrote: * Please remove colloquialisms. Characterizations such as "fantastically useful" are unlikely to be a convincing motivator and have no place in a DIP. * The "Description" section should be more detailed and less casual. The grammar changes should be shown in a syntax similar to the current grammar definition. These were not documented as a requirement anywhere that I saw. I'd have been happy to comply, if I had known this was the practice. I don't know enough about how D is compiled to speak meaningfully about implementation details. I am clearly not the only one who's convinced this is a useful feature. I welcome you or anyone else who can more effectively express the idea to make their own contributions to the DIP. On Wednesday, 28 September 2016 at 07:47:32 UTC, Andrei Alexandrescu wrote: * I saw in the forum that the "else" clause is supposed to run in the scope of the "try" statement, but that is not mentioned in the proposal. Even though that is the semantics in Python, that should be explicit in the document. The proposal should be standalone and fully specified without knowing Python or perusing external links. * The fact above (the "else" clause continues the scope of the statement after "try") is surprising, considering that the "catch" and "finally" clauses introduce their own scopes. The irregularity may confuse users. If the "else" clause is defined to introduce its own scope, it seems the advantages of the proposal are diminished. It was an idea that was raised, yes. If catch and finally don't continue the scope of try, then neither should else. That said, it might be preferable if they all did continue try's scope. But this would be a distinct and separate change. * The "Breaking changes" section should include how the following change in semantics would be addressed. Consider: try if (expression) try { ... } catch (Exception) { ... } else { ... } finally { ... } This code is currently legal and binds the "else" clause to the "if" and the "finally" to the first "try". The proposed feature will bind the "else" and the "finally" to the second try and then probably fail to compile because there is no "catch" or "finally" matching the first "try". This possibility hadn't occurred to me. Is that really legal? If so, I'd argue the old behavior should be maintained and also that people shouldn't write such ambiguous code.
Re: DIP 1002 (TryElseExpression) added to the queue
On Wednesday, 28 September 2016 at 07:33:48 UTC, ikod wrote: Thanks! There is also useful for/else construct in Python https://docs.python.org/2/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops I'd like to see it in D. While I appreciate being able to use for/else and while/else in Python, in D using gotos provides a more flexible (if more archaic) solution. But if we were to borrow else from Python for loops - which isn't a terrible idea since gotos are messy and make code harder to read - I'd suggest augmenting the construct with another block that evaluates only when the loop _wasn't_ broken. Make a DIP!
Re: Overloading relational operators separately; thoughts?
I'd also like to point out a generally sound design principle: Give the programmer as much power and flexibility as possible - but don't forget to provide tools for simplifying common use cases, and don't forget to define sensible defaults. It makes a lot of sense that opCmp and opEquals exist, they fit the by-far-most-common use case perfectly, but they aren't always flexible enough for what the programmer wants to do. What if comparison operators should return something other than booleans? What if `!=` should be implemented differently from `==`? These overrides great tools to have, but it would be better if they weren't the only options we had. Similarly, it makes a lot of sense that postfix operators are rewritten in terms of prefix operators, but that's not always flexible enough for what the programmer wants to do. It's a great default to have, but it would be better if we also had the option to define our own distinct behaviors for postfix operators.
Re: Overloading relational operators separately; thoughts?
On Wednesday, 28 September 2016 at 03:28:50 UTC, Minty Fresh wrote: Using strings and mixins does have quite a number of downsides. The additional work required to past the DSL aside, you also usually lose the scope in which things are declared (especially if you wish to reference or declare variables/functions/other constructs within your DSL), error reporting becomes much less precise, and the transition between the outer code and the inner DSL becomes jarring (especially in terms of syntax highlighting). That said, I love the fact D has a separate operator for concatenation. It's extremely useful to not have that ambiguity. Another thought is, operators not behaving as expected doesn't strike me as a failure of the language, given the language supports operator overloading. It's a failure in documentation to explain what the operators are intended to do, or a failure in implementation to behave as they should. I agree that opCmp has the benefit of unambiguity, but I still think Minty makes very good points. I think the cleanest possible solution would be to allow comparison operators to be overridden with opBinary and opBinaryRight, as well, but use opCmp and opEquals instead if they exist. I can't think of any way this would break existing code. On Wednesday, 28 September 2016 at 09:48:48 UTC, Matthias Bentrup wrote: In Mathematics the comparison operators are also commonly used for semi orders, which cannot be implemented by opCmp, because opCmp has no way to indicate that two values are incomparable. Interestingly the floating point types are semi ordered (due to NaNs), and for those D has some (non-overridable and deprecated) operators like !<, which would be easily extendable to any semi order, whereas the suggested replacement (i.e. test for NaNs manually) works only on floats. It's probably a terrible idea, but I'd love if those FP comparison operators would be de-deprecated and made possible to overload using opBinary. On Wednesday, 28 September 2016 at 06:05:54 UTC, Jonathan M Davis wrote: The increment and decrement operators are in a similar boat to the comparison operators in that post and pre can be derived from a single function. So, it's not just the comparison operators that got combined. Incidentally, I'm a little surprised and disappointed that D doesn't allow pre- and postfix operators to be separately overloaded. Postfix operators should default to their current behavior, where `x` is the same as `auto t = x; x = x; return t;` where prefix unary is defined, but I also think it'd be fantastic if we introduced an opUnaryPostfix override. (And should that be done, for the sake of clarity, it might be a good idea deprecate usage of opUnary in favor of calling the method opUnaryPrefix.)
Re: DIP 1002 (TryElseExpression) added to the queue
On Tuesday, 27 September 2016 at 10:05:20 UTC, Idan Arye wrote: BTW, if this feature is ever implemented in D, it's important that the else clause will continue the try clause's scope. The catch and finally clauses do currently continue the scope, right? (If they don't, they probably should, too.)
Re: DIP 1002 (TryElseExpression) added to the queue
On Tuesday, 27 September 2016 at 09:48:42 UTC, Jonathan M Davis wrote: And why not just put the code that would go in the else at the end of the try block? Just like with this proposed else, the code would only run if the preceding code didn't throw any exceptions. This just seems like an attempt to make D more like python rather than to add anything useful. - Jonathan M Davis This is a commonly-used tool that makes code more readable and cuts down on programmer error. It's far more concise and digestible than the functional equivalent, which is _not_ to put the code at the end of the `try` block, it's to put it in the `finally` block - refer to the DIP's example for how that works. This is the most important difference between using `else` and doing what you described: Exceptions thrown by the code in the `else` block are not caught by the `catch` statements intended to handle errors by the operation in the `try` block, but not to handle errors resulting from attempting to handle a success state.
Is there any way to have [] overloads use compile-time indexes as is currently done for Tuples?
I'd really like to define my own types that accept indexes for opIndex and opSlice as template arguments. Is there any way to do this? If not, this seems like an obvious thing to add to the language - what's been holding it back?
Re: how to access struct member using [] operator?
On Sunday, 25 September 2016 at 16:07:59 UTC, Basile B. wrote: WooW I have to say that I'm mesmerized ! How can this works ? "member" is run time variable so the return type shouldn't be inferable. The int fields are promoted to and returned as floats.