Re: Go 1.9
On Friday, 23 June 2017 at 20:13:15 UTC, Paulo Pinto wrote: ExcelsiorJET is quite easy to figure out, you can download their open source version. So in other words, you do not have used these products and only read their websites, got it. Some products go the static linking way, others map .jars into shared libraries. And how does the tool know which .jars to compile to shared libraries without running the code first? It can't. Which is why Excelsior ships with a JIT: From https://www.excelsiorjet.com/ "First, the AOT compiler turns your jar and class files into a conventional binary executable. That executable is fully interoperable with our JVM, which includes a JIT compiler to handle any classes that were not precompiled." Nice how you overlook the fact that .NET Native requires static linking, hence why there are such issues. AOT compiling to native code with either NGEN or Windows 8 MDIL compiler doesn't have such issues, because dynamic linking is used instead. Again, how can you compile ahead-of-time when you don't know the dependencies before running the program? You can't which is why every such tool is at a fight with how these languages work. In any case, even if native compilation toolchains for Java and C# aren't perfect, they make it less appealing to try out D if you don't come up with a solid history to go against them, that make people actually curious to try out D. That's just "I looked at the websites, never used these tools in practice but found them convincing" phrased differently to pretend you have an argument. The success of Go strongly indicates people generally don't connect Java/C# to "native code" or "slim binaries without dependencies", whom are you kidding here.
Re: Go 1.9
On Thursday, 22 June 2017 at 11:27:47 UTC, Paulo Pinto wrote: Java is AOT compiled to native code via Excelsior JET, IBM J9, IBM Websphere RealTime, JamaicaVM, SubstrateVM, Android ART and eventually Java 10. Have you used one of these products? How do they deal with dynamic class loading? I know how JamaicaVM does it, no thanks. C# is AOT compiled to native code since day 1, via NGEN, althouth it isn't an optimizing compiler and only supports dynamic linking. From https://docs.microsoft.com/en-us/dotnet/framework/net-native/net-native-and-compilation "Because the .NET Native tool chain links implementation code into your app only if it knows that your app actually invokes that code, either the metadata or the implementation code required in the following scenarios may not be included with your app: * Reflection. * Dynamic or late-bound invocation. * Serialization and deserialization. * COM interop. If the necessary metadata or implementation code is absent at runtime, the .NET Native runtime throws an exception. You can prevent these exceptions, and ensure that the .NET Native tool chain includes the required metadata and implementation code, by using a runtime directives file, an XML file that designates the program elements whose metadata or implementation code must be available at runtime and assigns a runtime policy to them. The following is the default runtime directives file that is added to a Windows Store project that is compiled by the .NET Native tool chain: ..." Better learn what the competition is actually doing. Reflection and dynamic class loading are essential parts of C# and Java and do not work well with AOT compilation and never will. Money can't patch over design mistakes.
Re: Interior pointers and fast GC
On Sunday, 22 January 2017 at 06:28:35 UTC, Chris Wright wrote: On Sun, 22 Jan 2017 05:02:43 +, Araq wrote: It's an O(1) that requires a hash table lookup in general because allocations can exceed the chunk size and so you cannot just mask the pointer and look at the chunk header because it might not be a chunk header at all. Know any production GCs that use hash table lookups for pointer assignments? Me neither. Ok ok, maybe Go does, it's the only language with GC that embraces interior pointers as stupid as that is. Overexplaining because I'm tired. If you have fixed-size allocations, you get much better time: O(log #pools) to find the pool, O(1) to find the offset in that pool. The cost is you multiply the number of pools in existence by the number of allocation sizes you decide to support. Sure, O(log #pools) + O(1) is "much better" than O(1). To shorten the discussion: You're looking for a variant of "card marking". No overhead for interior pointers if you do it right. I think, never worked out the details though. http://stackoverflow.com/questions/19154607/how-actually-card-table-and-writer-barrier-works
Re: Interior pointers and fast GC
On Saturday, 21 January 2017 at 17:42:46 UTC, deadalnix wrote: 1. Split the heap in chunk of size n being a power of 2, say 4M. Align them 4M. 2. Find the chunk an alloc is part of in O(1) bu masking the lower bits (22 bits to mask in our 4M case). 3. Have a table of page descriptor in the chunk header. Lookup the page the alloc is in in O(1). 4a. If the alloc is large (flag in the page descriptor), find the base pointer in O(1). 4b. if the alloc is small, compute the index of the item in the page from the size class in the page descriptor (on addition, one multiply and one shift) in O(1). Start on false premise, end up nowhere. It's an O(1) that requires a hash table lookup in general because allocations can exceed the chunk size and so you cannot just mask the pointer and look at the chunk header because it might not be a chunk header at all. Know any production GCs that use hash table lookups for pointer assignments? Me neither. Ok ok, maybe Go does, it's the only language with GC that embraces interior pointers as stupid as that is.
Re: RFC in Comparison between Rust, D and Go
On Wednesday, 11 November 2015 at 18:25:59 UTC, deadalnix wrote: Nim does everything according to their marketing department. The engineering department remains to be found. Pretty sure you know where you can find me and discuss these things with me. Not sure if I count as a software engineer by your twisted logic though. Either way I won't say more here because then Reddit will complain again and I try to always obey.
Re: Why I'm Excited about D
So, to be more specific, here is one of cases where it actually caused trouble in practice. Someone has originally written code that looked roughly like this: while (something) { // ... auto str = format("%s", parser.node); } Long time later I have been adding trace logs to that module and this has become akin to while (something) { log(parser.node); // ... auto str = format("%s", parser.node); } Which resulted in broken application. It took almost an hour to bisect all changed to trace the failure to this specifc line and realize that `parser.node` wasn't just trivial getter but method which actually advanced internal iterator to next node while returning current one. In Java many people would have done this instead: while (something) { log(parser.getNode()); // ... String str = format("%s", parser.getNode()); } Because trivial accessors are everywhere in Java one usually has to assume it has no side-effects. I fail to see the relevance of the missing () in your example; () doesn't scream side-effect in C++/Java/C#/C. The real issue here is that 'node' or 'getNode' is simply poorly named suggesting it has no side-effects. 'nextNode' for instance doesn't have this problem.
Re: Do everything in Java…
On Wednesday, 10 December 2014 at 23:23:50 UTC, Walter Bright wrote: On 12/10/2014 4:15 AM, Paulo Pinto wrote: I prefer the model used by the referred languages, where binary libraries and metadata is used, instead of the C toolchain model. For example, just shipping the .TPU/.DCU libraries in the Object Pascal world. If the metadata had enough info in it to do inlining, it might as well be the source code. Er ... but you're the guy who stresses that lexers cannot be fast enough because they need to look at every input char. (And you're right.) You can at least cache the lexing step. Not that D's compiler is not fast enough anyway, I'm just saying that your statement is really weird.
Re: 'int' is enough for 'length' to migrate code from x86 to x64
no, the problem 2 just becomes hidden. while the given code works most of the time, it is still broken. You cannot handle stack overflow in C reliably or out of memory conditions so "fails in extreme edge cases" is true for every piece of software. "broken" is not a black-white thing. "Works most of the time" surely is much more useful than "doesn't work". Otherwise you would throw away your phone the first time you get a busy signal.
Re: 'int' is enough for 'length' to migrate code from x86 to x64
Most of the statements I disagreed with were opinions. "unsigned" means "I want to use modulo 2^^n arithmetic". It does not mean, "this is an integer which cannot be negative". Opinion. Using modulo 2^^n arithmetic is *weird*. Opinion. If you are using uint/ulong to represent a non-negative integer, you are using the incorrect type. Opinion. I believe that bugs caused by unsigned calculations are subtle and require an extraordinary level of diligence. Opinion (correctly qualified as belief). It's not only his "opinion", it's his *experience* and if we want to play the "argument by authority" game: he most likely wrote more production quality code in D than you did. Here are some more "opinions": http://critical.eschertech.com/2010/04/07/danger-unsigned-types-used-here/
Re: Why is `scope` planned for deprecation?
I think it make sense to have something for ownership. The error of rust wasn't going that road, but going in that road 100%, which come at a cost at interface level which is too important. A simpler ownership system, that fallback on the GC or unsafe feature when it fall short. I'm confident at this point that we can get most of the benefit of an ownership system with something way simpler than rust's system if you accept to not cover 100% of the scenarios. Do you happen to have any concrete reasons for that? An example maybe? Maybe start with explaining how in detail Rust's system is too complex? I'm sure the Rust people will be interested in how you can simplify a (most likely sound) type system that took years to come up with and refine.
Re: The cost of write barriers
Would such an implementation also be possible in a language like Go or D with internal/'thin' pointers? Last time I thought about it, card marking is indeed the only write barrier that is not affected by interior pointers. I could be totally wrong though.
Re: The cost of write barriers
On Sunday, 2 November 2014 at 08:48:46 UTC, Jonathan Barnard wrote: The upcoming version 1.4 of Go uses write barriers in preparation for the future implementation of a concurrent and generational GC. On the mailing list thread discussing the beta (https://groups.google.com/forum/#!topic/golang-nuts/7VAcfULjiB8), a few people note speed reductions of 30-50% in their benchmarks. I think this vindicates to a degree D's decision to avoid garbage collection strategies that require write barriers. And I think these are meaningless results. You can see here for instance what a write barrier can look like: http://psy-lob-saw.blogspot.de/2014/10/the-jvm-write-barrier-card-marking.html
Re: C++ developer choices in open source projects
It's probably a good thing they don't know what C++11 is, otherwise they might start writing even more horrendous code using operator""(). I suppose I've been a frog in the well, but it was only yesterday when I discovered that C++11 allows user-defined literals via operator""(). Skimming over the docs for that today, I couldn't help but shake my head at just how wrong the whole conception of it is. It's just *asking* to be abused for writing inscrutable, unreadable, unmaintainable code. I honestly have trouble imagining any sane use case for it apart from submitting obfuscated code contest entries. But hey, what's one more nail in a coffin already crawling with monstrosities like Boost.Xpressive? Yeah, who cares about language extensibility or useful features. These all beg to be abused. Let's all use Go instead.
Re: So what exactly is coming with extended C++ support?
It doesn't mention anything about moving C++ into C#. Even with IL2CPP, C# has fundamental design trade offs that make it slower than C++(GC is just one of them), so it wouldn't make much sense to port engine code to C# unless they wanted it to run slower. What are these fundamental design trade offs?
Re: assert semantic change proposal
Furthermore, I think Walter's idea to use asserts as a source of optimizer hints is a very powerful concept that may turn out to be a revolutionary feature in D. It could very well develop into the answer to my long search for a way of declaring identities in user-defined types that allow high-level optimizations by the optimizer, thus allowing user-defined types to be on par with built-in types in optimizability. The answer to your search is "term rewriting macros (with sideeffect and alias analysis)" as introduced by Nimrod. Watch my talk. ;-) 'assume' is not nearly powerful enough for this and in no way "revolutionary".
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
On Thursday, 17 July 2014 at 15:38:44 UTC, Tobias Müller wrote: "Araq" wrote: The paper focusses on RC vs "tracing". My point is "tracing" vs "copying" is another tradeoff. Here is a mark&sweep algorithm: - Trace live objects. - For each dead object: Deallocate. Here is a copying GC: - Trace and copy live objects. - There is no deallocation step. The old region is free for further usage. It's more like: ... Your description is still naive and as such your post is more misleading than helpful. My description is naive to get the basic point across, I have no idea what the point of your post is.
Re: GCs in the news
I feel it is a major concern, if I'm starting a project with low latency requirements* I certainly think twice about using D. I think this could apply especially to people outside the community who might not have experienced the benefits D provides. The issue is not there is a GC, it's that the GC is viewed as bad. If the GC was as good as Azul's C4 GC then D would be perfect. I'm not sure if D's memory model supports such a collector though. It doesn't.
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
Yes, and my point was that you pay for the (implicit) deallocation by the need to copy all live objects. The cost of copying is not zero compared to a non-copying GC. No matter how you do it, the cost has to be paid *somewhere*. It's just a question of which method will be less costly based on what your application does. The cost models are vastly different and as you finally note application dependent. *The* cost does not have to paid *somewhere* because there is not a single cost to begin with.
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
On Wednesday, 16 July 2014 at 18:24:11 UTC, H. S. Teoh via Digitalmars-d wrote: On Wed, Jul 16, 2014 at 06:11:54PM +, Araq via Digitalmars-d wrote: On Wednesday, 16 July 2014 at 16:57:18 UTC, Kagamin wrote: >On Tuesday, 15 July 2014 at 20:44:35 UTC, H. S. Teoh via >Digitalmars-d >wrote: >>Not to mention, when you need to deallocate a large complex >>data >>structure, *somebody* has to do the work -- either you do it >>yourself, or the reference counting implementation, or the >>GC. > >The first and the last options are still prominent. A copying GC copies the live data, deallocation of a large complex data structure is free in this scenario. Same if you use a manually managed memory region for the data structure and then deallocate the region via some batch operation. But hey, this simple fact must be wrong because some guy read a single paper about GCs that doesn't even cover this point. Have you even read the paper? What you just said is exactly what the paper is describing. There are two ends of the spectrum of memory reclamation algorithms, at one end, you're tracing "matter" (live objects), and the other end you're tracing "antimatter" (dead objects). They are just duals of each other, and optimized GC/RC algorithms tend to approach the middle ground, with time/memory tradeoffs as an adjustable parameter. The paper focusses on RC vs "tracing". My point is "tracing" vs "copying" is another tradeoff. Here is a mark&sweep algorithm: - Trace live objects. - For each dead object: Deallocate. Here is a copying GC: - Trace and copy live objects. - There is no deallocation step. The old region is free for further usage.
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
On Wednesday, 16 July 2014 at 16:57:18 UTC, Kagamin wrote: On Tuesday, 15 July 2014 at 20:44:35 UTC, H. S. Teoh via Digitalmars-d wrote: Not to mention, when you need to deallocate a large complex data structure, *somebody* has to do the work -- either you do it yourself, or the reference counting implementation, or the GC. The first and the last options are still prominent. A copying GC copies the live data, deallocation of a large complex data structure is free in this scenario. Same if you use a manually managed memory region for the data structure and then deallocate the region via some batch operation. But hey, this simple fact must be wrong because some guy read a single paper about GCs that doesn't even cover this point.
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
On Tuesday, 15 July 2014 at 21:11:24 UTC, H. S. Teoh via Digitalmars-d wrote: On Tue, Jul 15, 2014 at 09:03:36PM +, Araq via Digitalmars-d wrote: > >The only way to *really* guarantee 100% predictable memory >reclamation is to write your own. Except that we all know how >scalable and bug-free that is. Not to mention, when you need >to >deallocate a large complex data structure, *somebody* has to >do the >work -- either you do it yourself, or the reference counting >implementation, or the GC. No matter how you cut it, it's >work that >has to be done, and you have to pay for it somehow; the cost >isn't >going to magically disappear just because you use reference >counting >(or whatever other scheme you dream up). > Actually it completely disappears in a copying collector since only the live data is copied over ... Nope, you pay for it during the copy. Read the linked paper, it explains the duality of tracing and reference-counting. Whether you trace the references from live objects or from dead objects, the overall computation is equivalent, and the cost is effectively the same. Once you've applied the usual optimizations, it's just a matter of time/space tradeoffs. This is wrong on so many levels... Oh well, I don't care. Believe what you want.
Re: LinkedIn Article to be: Why you need to start moving off C/C++ to D, now.
The only way to *really* guarantee 100% predictable memory reclamation is to write your own. Except that we all know how scalable and bug-free that is. Not to mention, when you need to deallocate a large complex data structure, *somebody* has to do the work -- either you do it yourself, or the reference counting implementation, or the GC. No matter how you cut it, it's work that has to be done, and you have to pay for it somehow; the cost isn't going to magically disappear just because you use reference counting (or whatever other scheme you dream up). Actually it completely disappears in a copying collector since only the live data is copied over ...
Re: Bottom line re GC in D
On Thursday, 10 July 2014 at 19:57:56 UTC, deadalnix wrote: On Wednesday, 9 July 2014 at 11:21:13 UTC, bearophile wrote: Adrian: As for your second question (i.e. how good the GC needs to be for me), I would probably be satisfied with a GC that matches the Java one This will not happen even in one hundred years. So if that's what you want, you will never be satisfied by D GC. Actually, I think we can do better than Java, because we have type qualifiers and less indirection. That isn't unseen: OCaml's GC is more performant than Java's. We certainly do not have the resources java has, but we have a language that is way more GC friendly. No, you don't. No distinction between GC'ed and non GC'ed pointers, interior pointers are everywhere, sharing GC'ed memory between threads is unrestricted, casting to const/immutable might be officially undefined but in practice abounds so you better don't take advantage of that, excellent C interop means that you have no chance but to scan the stacks conservatively.
Re: Software Assurance Reference Dataset
Spark is a research language that does not work, as I've discovered and discussed with you before. It cannot be determined the max stack usage at compile time, again, this is the halting problem. What?! It's easily solvable: Forbid recursion and indirect function calls and it's guaranteed that the program only requires a fixed size stack and you can compute an upper bound of the required stack size at compile-time. Which is BTW exactly what OpenCL does as GPUs tend to have no stacks. In what way is Spark a "research language that does not work"? And how many language design issues need to be discovered until you admit that Safe-D is a "research language that does not work"?
Re: A Perspective on D from game industry
The issue I have with metaprogramming (and overloading and some other similar ideas) is that it makes a statement dependent on a lot of context, this is tricky in a large team as now just reading a change doesn't really tell much. Our is an industry where we still exercise a lot of control, we want to know exactly what a statement does in terms of how it's executed. Can be easily solved by better tooling, esp since it's all done at compile-time. ("Show code after some/all transformations.") The lack of imagination among programmers (and even professional game developers) is just sad.
Re: Another way to do CTFE
On Tuesday, 17 June 2014 at 19:41:59 UTC, Ary Borenszweig wrote: CTFE is really nice but has its limitations: you can't do anything you want, and since it's interpreted it requires an interpreter and it's generally slow. Nimrod does the same thing, and now they are implementing a VM to run the interpreted code faster. Is this really the way to go? For your information the new VM shipped with 0.9.4 and runs Nimrod code faster at compile-time than Python runs code at run-time in the tests that I did with it. :-) That said, it turned out to be much harder to implement than I thought and I wouldn't do it again. ... The compiler could be smart and cache the executable so that anytime it has to expand it it just needs to invoke it (skip the compile phase). What do you think? It is a *very* good idea and this is exactly the way I would do it now. However, you usually only trade one set of problems for another. (For instance, giving Nimrod an 'eval' module is now quite easy to do...)
Re: Swift does away with pointers == pervasive ARC
I think D2 has too many competing features to experiment, so an experimental D-- implemented in D2 would be most interesting IMO. But it takes a group effort… :-/ What's the point? Nimrod already exists and answers most of your questions. If only you would know how to ask...
Re: Memory allocation purity
Yes, the VRP has been a nice win for D. No other language does it. I don't know why you keep saying things like that, you don't know all the languages out there. Nimrod does it too fwiw...
Re: More on Rust language
It increases the complexity to reason about code. No, that's wrong. Why it is wrong? Because it is much harder to reason about the same things without type system support.
Re: More on Rust language
It increases the complexity to reason about code. No, that's wrong. If the compiler does not give an helping hand, bugs are too easy to create. Usually a type system is used to increase safety...