>The programming language that empowers everyone to become a systems programmer.
>everyone to become a systems programmer.
Umm, am I the only one who thinks this is overly dramatic? Look at D's website
It's modern, yet not full of overwhelming colors or styling, doesn't turn you into a systems programmer, conveys just enough information.
IDK, maybe I'm getting old.
The idea that buffer overflow problems can be fixed with better programmers is completely unworkable. The best programmers in the business write buffer overflow bugs - because they're human, and people make mistakes, and software is complicated. Mechanical checking is the solution.
The problem is fixable in C, but nobody in the C community seems interested in it.
If you're fed up with the problem, you can always try DasBetterC.
It's so retarded because almost everything in the nomenclature will sound offensive out of context. Parent-child is especially fun:
Make a parent kill its children
Send a signal to hang child up
Dispose of children
EDIT: Found a real example of this while working on my project: https://dlang.org/phobos/std_ascii.html#.isWhite
I think there are other ways of helping on-board people from other backgrounds, especially with something like Go's tour. If you give people the path of least resistance to trying the code, it can feel much more doable. D's sample code selector https://dlang.org/ is pretty cool as well.
I feel as though this web design is less comfortable because I don't know where I am going. There is a TON of information on the front page, is there a link to the documentation in the middle of the page? How do I install? Is the install button behind "Get started" or is it on this front page? What does the Rust book look like? Is it the Rust book that Marcus told me about? etc.
When someone is completely new to the site, there is a lot to look at, and it feels a bit overwhelming.
It's a blessing it hasn't. Things unfold at their own intrinsic pace, and an influx of people who are concerned about popularity rather than whether it is a good tool for solving their own problems would have proved a challenge for the ecosystem at that point.
It is taking off though. The cumulative effect of compounded growth is easy to underestimate.
A line that was good for a laugh in Berlin - 'But there are no jobs in D', as I sat around a whole bunch of people who not only used D at work, but whose careers had progressed much more quickly as a result of their involvement with the community.
My favorite thing about D is its Uniform Function Call Syntax—any function you write can be called from any object of the first argument's type. For example if I have some pointless function:
string add_str(string s1, string s2) { return s1 ~ s2; }
that can be called as
string s1 = "apples, "; string s2 = "bananas, "; string s3 = "and oranges"; writeln(s1.add_str(s2).add_str(s3));
which would print "apples, bananas, and oranges"
This is cool stuff. I can comment on these from the perspective of the D language where some of these features have been present for a while:
Of the projected features:
One of the simplest (and IMO, best) examples is D's regex library. Using CTFE, it can take a regular expression and write an automaton to match it, in D, and then compile that into your program. So now instead of interpreting the expression into some bytecode and executing that in a virtual machine at runtime, you have a native state machine written specifically for each expression you're trying to match.
The D programming language will default initialize floating point values to NaN, rather than 0.0. The reason is so that the result of an erroneous 0.0 initialization may not be noticed, but NaNs propagate and you'll have a NaN in your results.
Nice article!
> D can define class invariants:
struct invariants as well, which, unlike in C++, are very different from classes.
> a contract clause that is checked before and after every method call
More correctly, "after every public method call" but the rules are a little more detailed. The reason is, private functions can be seen as supporting the public interface; so, what matters is the state after public function calls.
Ali
Eh, I think we all know what's likely to happen. We'll get something that sort-of-kind-of do the basics, but is very kludgy and lacking in apps while adding new stuff continuously; it'll nevertheless look and work like something straight outta 2010, and objectively suck ass in everything except privacy versus 2019 Iphones/Pixels.
Proponents will claim that it's a fucking miracle $1.5 million can get them a pocket machine that makes calls, sends email, plays certain games, has SSH out of the box and can compile D using nothing but its sweaty balls. Meanwhile detractors will argue, most likely correctly, that it's very likely to die out in a few years, it fucking sucks ass and can't even call you a cab, and everyone in his household spit at it within 30 seconds of attempting to use the thing, "I told you so". It's just... predictable.
D doesn't need a giant company backing it to succeed, and I don't think it would be so healthy for the language if there were one. There are quite a few companies using D, but mostly they just get on with things and don't speak that much about their use of D in public. I mean even Microsoft used D in the COM team a few years back, but they didn't exactly send out a press release on it. Web guys have a culture of talking, but the culture isn't necessarily the same in finance, for example, to name one area I know well.
D isn't like Go or Rust, which to my eyes have very particular use cases. It's much more ambitious as a language, which means baby more use cases but also a lower density of users in any particular sector. So in any one sector "I don't know many people in my area using D" because things are more spread out.
Pros and cons of that, but if certainly makes D conferences more interesting to go to.
I think there's a bit too much whitespace, it's a bit too spread out and feels poorly balanced. In particular the space under the heading blurb looks too big, like there's something missing.
Not a fan of the typography. The coloured half-height backgrounds on the headings makes already fairly annoyingly wide-fonted text even more difficult to read by adding additional unwelcome noise for my eyes to work to ignore.
There's an annoying mix of text that seems too small (the blurb in the Why/Build it in Rust sections) and text that seems too big (Rust in Production). Ironically the small bits have a better argument for being big than the big bits do (they have lower-contrast backgrounds to overcome).
The garish background colours don't help (and most of it seems to turn into a dirty grey colour for colourblind users). Looking at the beta site in comparison to the old one it's noticeable how my eyes relax on the more conservative design. Blasting big chunks of green and red at me does not make me want to point my eyes at what you've written.
The lack of code examples up-front is bit of a show-stopper too. A good example is worth a million breathless "Rust has great $x" sentences. And I don't mean the terrible example on the existing site - oh boy, this language makes it easy to match on magic numbers. The D site is more like what I want to see.
Some of the alt text looks superfluous. Like the WebAssembly icon having "gear with puzzle piece elements"
- a good rule of thumb is to write what you'd put there if images weren't a thing. In this case it's just a bit of visual style to support a heading, so the alt text should almost certainly just be ""
.
Please don't target="_blank"
me. I'm more than capable of opening a tab all by myself.
The get-involved
section has an unclosed div
in the header
- some HTML validation probably wouldn't go amiss.
Meanwhile in D, I feel stupid for forgetting about <code>TypedAllocator</code>. A single line of change later, the fixedSize
half of my crap is now region.
There are many D users interested/working in game development and real-time applications (e.g. real-time audio processing) so you're in a good company ;)
To be honest, while -betterC
is meant to make integration of D code in C/C++ projects seamless, I don't think it's necessary for your domain. Once you deal with the little extra complexity related to the build system, features like RAII (which does not depend on the GC) quite quickly make up for it.
In general, there are various techniques that people using D for those domains employ:
@nogc
attribute, which statically (at compile-time) enforce that those functions will not allocate memory from the GC (and not call any code that might) and therefore a GC collection will not happenGC.disable
before entering performance critical section of your programAnd as a general (not specific to D) advice, avoid dynamic allocation in performance critical parts of the code base, use resource pre-allocation where possible. Use custom allocators (see https://dlang.org/phobos-prerelease/std_experimental_allocator.html).
Of course compile-time sort is just a toy example. Where CTFE really shines is in combination with string mixins. You can write regular D code that parses strings, builds types and functions, and outputs the result as executable code. And it looks like D all the way through.
A fantastic example is Philippe Sigaud's Pegged, which generates code from a PEG and can create a DSL parser in just a few lines of code:
mixin(grammar(` Arithmetic: Term < Factor (Add / Sub)* Add < "+" Factor Sub < "-" Factor Factor < Primary (Mul / Div)* Mul < "*" Primary Div < "/" Primary Primary < Parens / Neg / Pos / Number / Variable Parens < "(" Term ")" Neg < "-" Primary Pos < "+" Primary Number < ~([0-9]+)
Variable <- identifier `));
// Parsing at compile-time: enum parseTree1 = Arithmetic("1 + 2 - (3*x-5)*6");
pragma(msg, parseTree1.matches); assert(parseTree1.matches == ["1", "+", "2", "-", "(", "3", "", "x", "-", "5", ")", "", "6"]); writeln(parseTree1);
// And at runtime too: auto parseTree2 = Arithmetic(" 0 + 123 - 456 "); assert(parseTree2.matches == ["0", "+", "123", "-", "456"]);
D is getting pretty close.
Great things about it...
https://dlang.org/spec/type.html
Byte, short, int, long defined as 8,16,32,64 alas, has the same horrible overflow semantics as C...
...but fixable in by library https://dlang.org/phobos/std_experimental_checkedint.html
That library is an amazing example of the power of Design by Introspection, allowing the user to select which overflow handling strategy to employ.
These issues exist in most languages designed before Go, but languages since Go that put even a half-hearted effort into concurrency issues address them. Go put in some effort but did nothing to address data races.
The standard way of addressing the possibility of data races is to introduce some level of immutability to the type system. In the D programming language, for instance, I can create an object of type Foo
and mutate it, and then use assumeUnique
to turn it immutable. From then on, nobody can alter it, and it's safe to share between threads.
Or a function might take a const Foo
as a parameter, which means it promises not to change that value, but it doesn't need to make sure that nobody else will ever need to change it.
I believe Rust tries to push you into using immutable data, and it does complex flow analysis to protect against data races.
> Regarding that copy operation :=
, does it also working like that in other languages (C#/java for example) for reference type? Of course it can be mitigated by struct / value type.
It works just like C# and Java, except that you don't have a builtin Cloneable
interface to standardize how to copy objects. And using structs gives you a shallow copy; if you have a mutable array as a struct member, it's not copied.
> And why does the side effect at "slice gotchas" section possible? It looks like a very bad bug to me.
It's not a bug, it's a footgun. Sometimes you want this behavior, a lot of the time you don't, and the only solution is to copy everything everywhere, manually. A type system that lets you mark variables immutable or const would address this pretty thoroughly.
> The front end for the dmd D compiler is open source. The back end for dmd is licensed from Symantec, and is not compatible with open-source licenses such as the GPL. Nonetheless, the complete source comes with the compiler, and all development takes place publically on github. Compilers using the DMD front end and the GCC and LLVM open source backends are also available. The runtime library is completely open source using the Boost License 1.0. The gdc and ldc D compilers are completely open sourced.
You might find this post from the D Blog interesting. Funkwerk is a German company that switched from Java to D starting in 2008, and this post describes a little of their experience.
> If you give people the path of least resistance to trying the code, it can feel much more doable. D's sample code selector https://dlang.org/ is pretty cool as well.
I thought the five links to different kinds of Rust use cases was pretty brilliant actually, and it's right there near the top of the site. I don't think that's too much of a barrier to "getting to the code", and at the same time it tells a clear story about what Rust thinks it's good at right now.
Also I don't wanna dunk on dlang.org too much but it could really use some love from someone with design skills, the very poor use of spacing and typography makes the page look noisy and distracting even though the content is pretty good.
Edit: One thing I didn't like about the new Rust site and that dlang.org got right: is it some kind of tradition that the code examples on the Rust site are never allowed to fit in the box they're shown in? What is up with that? They should call their designer back and tell them the code needs to look good :)
Nim and Zig look quite interesting. I hope they succeed. They are also quite new languages without many industrial users or that many contributors. D goes back to 2001 or something - it's been around a while, quietly growing at an impressive compounded rate. The adoption into GCC might turn out to be quite important.
https://dlang.org/orgs-using-d.html
I was speaking to the CTO of Weka.io, creator of the world's fastest file system. He heard about D in 2014 from a tweet by Kent Beck and, as you do, proceeded to base his entire company on it. They couldn't have accomplished what they did in that amount of time had they picked a more conventional choice. And nobody in their right mind will write a filesystem that stores hundreds of petabytes or more across all their customers in a very new language like Nim or Zig.
So what's the appeal of D? It's a productive and pragmatic language that allows you to accomplish things in a way that's sensible. Code is plastic and readable and that matters because a big contributor to complexity is when you are stuck with the choices you made early on.
Don't forget to check out existing implementations like
https://dlang.org/blog/2017/08/23/d-as-a-better-c/
https://dlang.org/spec/betterc.html
I'm sure you can easily find a subset of Nim that can act as a better C. You can start by disabling the garbage collector.
Oh, we discussed that numerous times. And the gist of those discussions is that there are quite a lot of people who require backward compatibility. Things preventing C++98 code to be used by C++next are very unlikely to get approved by the commitee, because adapting existing codebases to major language changes is simply infeasible.
The python (r)evolution has been sort of a disaster -- there are major projects like gyp where it took a decade until people even started porting. Such a split is absolutely harmful to the ecosystem.
However, one should mention the Epoch proposal which tried to provide a mechanism for language changes while maintaining a "sufficient" degree of compatibility with existing code. It currently seems to be the most feasible approach, but it is uncertain whether its issues (with e.g. concepts) can be resolved.
I recommend taking a look at D or Rust which could be remotely considered as "newer more modern" versions which may or may not fit your bill.
https://dlang.org/ shows you a selection of snippets. Including one ("Tiny RPN calculator") by yours truly (Technically, I wrote the initial code but someone else used static foreach which I didn't know existed).
One really successful feature of D is the built-in unittesting feature. Although it seems trivial, the fact that it is built-in and always available has made it transformative in that code just isn't complete until there are unit tests.
LDC 1.4.0-beta1 is out now.
The highlights of version 1.4 in a nutshell:
Full release log and downloads: https://github.com/ldc-developers/ldc/releases/tag/v1.4.0-beta1
Oooh, I know stuff about this :)
D was a language suggested to be a successor to C++. it was first released in 2001, and has similar syntax https://dlang.org/
Also a fun etymology fact is the early computer language BASIC had a retro-fitted acronym attached to it, because back then EVERYTHING was an acronym. So instead it was Beginner's All-purpose Symbolic Instruction Code.
The act of creating an acronym retrospectively like that got named Backronym. :)
This version of D was released November the first.
Link to the full change-log: https://dlang.org/changelog/2.083.0.html
TL;DR:
D: - Cpp runtime version check - New less conflicting way of declaring C++ linkage via a string - New trait isZero - New trait getTargetInfo - New pragma linkerDirective
Phobos: - std.algorithm.iteration.each is now capable of early-stopping
Dub: - betterC build option has been added
DasBetterC doesn't support unittests, as the unittests require having a D main
function rather than a C main
function. However, this particular program could be easily converted to a straight D program by changing the main()
and then compiling without -betterC
, and then unittests can be added.
But also I made no attempt to take advantage of D features with this project, it was just a straight conversion.
Sufficiently well for releasing "Quantum Break, the first commercial AAA game to ship with bits implemented in D"
Since they were the first, I can't say it was smooth for them, but they have now ironed out the kinks(so that's easier for the rest of us) and released their open source framework.
https://github.com/Remedy-Entertainment/binderoo https://dlang.org/spec/cpp_interface.html https://dlang.org/blog/2016/07/25/d-in-games-ethan-watson-of-remedy-games-goes-to-gdc-europe/
I think the only details missing from that page are probably the specific language features that depend on garbage collection. Those are listed here:
https://dlang.org/spec/function.html#nogc-functions
If you would, I'd love to hear why you're looking into BetterC.
No, gc is still there, but apparently there's a minimal runtime, good you can jump through, and eventually back the language into behaving well enough for writing, say, an OS kernel. But the writeup on using D to create the powernex kernel falls somewhat short of being an endorsement of the language's suitability for that purpose.
Well I support any efforts to promote UFC and brainstorm solutions that would appease the objector's concerns to finally get it in, even if I don't favor the "!
" because it reminds me too much of template/macro calls from D and Rust. Though, I also don't know that alternative symbols would be better either 🤔 (e.g. foo'(x)
, foo#(x)
, foo@(x)
, foo$(x)
, foo~(x)
, foo:(x)
, ...), each with varying pro's/con's, from reachability on non-English keyboards to clashes with future potential uses (e.g. $
for metaclasses, @
as a potential complication for linkers, ~
as a potential future binary operator like D to clearly distinguish concatenation for vectors vs overloaded addition ...). Keep it up.
Rust's metaprogramming is totally unlike what Andrei and Walter were aiming for. D aims to be safe, but that's far from everything.
Rust currently has better safety mechanisms than D, but if you ask around on the D forum you'll likely find that people are there (rather than using rust) due to the other features D has - https://dlang.org/ Look at the examples here: Rust can do short and sweet too, but it doesn't have some constructs that make these possible. (Obviously, I highly recommend "Tiny RPN Calculator" originally written by your's truly)
/uj
> The reason why JS has been eating the world is because most languages
> (1) cannot be run on multiple devices and platforms,
And yea C/C++, pretty much anything on the JVM.
> (2) are not performant enough,
C/C++ and D, bro.
> (3) don’t have a good/versatile concurrency model,
Also assuming JS has any sort of real concurrency model, and even if it did like it wouldn't be shit.
(4) have bloated and hard-to-master libraries,
D, unless you can't read and/or don't understand pointers and/or can't understand type systems.
(5) only are useful in certain problem domains,
Why do he think there's so much C/C++ code out there then? Also try D, bro.
(6) are too fractured across problem domains and don’t have a big enough community to support users overall.
Every heard of forums? It's like where you put a short blog post explaining an question/issue you have, and people will respond to tell you what an idiot you are/give you an answer to your question/problem.
> …So …but … can we create something better than JavaScript?
It's almost like we already have.
> - Automatic GC and memory management.
Not gonna get "TEH MAX PURFORMANCSE" that way, bro. Again why the fuck do you think C/C++ is so widely used?
Also with D you can either use the builtin GC or opt out with @nogc
.
> The best of both worlds when it comes to functional/object-oriented, aka, why not both?
> Has first-class functions. Template literals. Anonymous functions, closures, etc.
> Has solid language-level support for immutability and immutable data structures etc.
D, D, and also D.
Ok I'm done unironically shilling D now.
I think it's a language feature in Haskell but laziness is routine for D programmers as well. Just as an example, std.range.recurrence uses lazy Fibonacci series as an example: https://dlang.org/phobos/std_range.html#recurrence
And I show an explicit range interface for the same: http://ddili.org/ders/d.en/ranges.html
To me, Go very much is the C philosophy of programming but lifted into a different domain. i.e. One where a runtime is fine. The thing about Go though, is that in C I will find myself writing runtime enabled generic code, while Go doens't even feature such things. So it also feels like it's trying to recreate C too much.
D I think suffers from not getting a solid launch, and essentially having other alternatives beat it to the punch. C++11/14/17 basically takes away the flame of D's original mission statement. Go brings back the simple static natively-compiled language to the world of interpreters, dynamic typing, and vms. Rust raises the bar on static compiled languages and arguably solves the more foundational problems of that language domain. So D wasn't really chasing the most critical shortcomings of C++, a reason why people just waited for C++ to get better.
The one cool feature of D that I'd really like a reason to play around with, is -betterC. Which has been intriguing me ever since I first heard of it.
Rust has already been mentionned so I'll root for D.
D, if used with its runtime, has about the same expression level as C# but being compiled it doesn't so it can easily solve most highlevel problems way faster while still being very safe.
Without its runtime it can be used as a safe C: it has the exact same expression level and can be as unsafe if needs be, but provides templates, bound checking and other nice compile-time things to make programming easier and less error-prone while retaining the speed.
Start with the reference dmd (now at 2.075.1) implementation - https://dlang.org/download, go through some books, tutorials (https://tour.dlang.org/), play with some code on https://code.dlang.org/ and when you're ready you'll have a pretty good understanding of which compiler to choose.
> A garbage collector brings an overhead that slows down languages
Overhead when doing what? Allocating? Freeing? Linking to a runtime (binary size overhead)? Ram usage? What kind of a GC? GC implementations make different trade-offs.
> It creates random milliseconds of pauses
Only if it ever collects. A similar effect can happen when a C++ std::shared_ptr
goes out of scope. Shared pointers are GC, just not tracing one, and have yet another set of trade-offs (like having to explicitly use weak references).
> if performance is important to you, non-gc is the way to go
Not in my experience, or in benchmarks I've seen / done. And when the GC gets in the way - don't allocate on the GC heap. For some languages (Java, cough), you don't have that choice, but that's a characteristic of those languages, not of having a GC.
Take D. If the GC never kicks in (which is easy enough to ensure through several means), and assuming there's any dynamic memory allocation going on anyway, it'll be faster than C++/Rust since the memory is never freed.
For the conference? Too early to say. We've only just opened for submissions.
Or if you mean in general, see Spasm. The author is working on porting DRuntime to WebAsm.
A few thoughts:
@nogc: Most of the time, you don't have to worry about it. I realize some people have this built-in aversion to garbage collection, but the situation isn't as bad as they make it out to be. It's quite useful for most apps when you account for it and architect your code for it. There is a class of apps for which D's GC will be problematic, but that does not include 2D hobby games. I linked the blog's GC series in another comment, but here it is: https://dlang.org/blog/the-gc-series/. There's some tips and tricks there for making effective use of the GC.
@nogc and Phobos: There is no intention to ever make Phobos fully @nogc compatible. The ongoing work is looking to weed out GC usage where it isn't absolutely necessary and provide, where possible, @nogc alternatives to functions where it can't be weeded out. The goal has never been 100% compatibility.
BetterC: No D app should start out with this unless the developer has a very specific use case and a full understanding of why it's being used. It is intended primarily to enable easier porting of C and C++ projects to D. You lose too much to justify using it (as you pointed out).
D is perfectly usable right now in a "it works" mindset rather than a "well, it kinda works" one. Major changes like safe-by-default and @live will be given ample preview periods before they become the default. That will give you time to gradually adapt your code base (e.g. do a preview compile to see what works and where you need to add @system and implement @trusted bridges). And if you don't want to adapt, you can maintain your code with an older version of the compiler (or use the -revert switch to turn off a feature). It might not be entirely headache free initially, but for your use case I expect the headaches will be minor and easily solved.
>there are many more commercial and free uses of D for large projects than there is of Rust. Usage of Rust is barely a rounding error at this point
Do you have any hard numbers to support this strong claim? Judging by github stats Rust leaves D in the dust by a wide margin. And considering that D is a significantly older language it's not a good sign.
It's harder to measure commercial uses, but lets compare list of organizations for Rust and D. Even by being generous I can't see how you can call it a "rounding error". And Rust has a number of widely known organizations which use it: Dropbox, NPM, Baidu, Yelp, Google (see e.g. Fuchsia OS project), Microsoft (also see actix-web
), NicoVideo, etc. D also has its share of famous commercial users, but again I don't see the superiority claimed by you.
I expect to not lose core language features that are part of the reason to pick the language in the first place!
> D features not available with BetterC:
> 1. Garbage Collection 2. TypeInfo and ModuleInfo 3. Classes 4. Built-in threading (e.g. core.thread) 5. Dynamic arrays (though slices of static arrays work) and associative arrays 6. Exceptions 7. synchronized and core.sync 8. Static module constructors or destructors
Sum-types are in the standard library. As for pattern matching, it's been implemented, if hackily.
> Error messages can be as precise as you want
With D's compile time metaprogramming, static assert can be and is used to generate custom error messages.
"Better C" is basically D's version of -ffreestanding
—a compiler switch for producing binaries that don't depend on the D runtime or standard library.
I'm late to the party, but I'd say D is a pretty decent programming language modeled after c++ with some more modern design changes. One thing about it though is that if you need really high performance D has a garbage collector that can sometimes pause the thread, but this isn't really an issue for most applications.
You shouldn't rely on the order of evaluation of the arguments in a function call:
> Order Of Evaluation
> Binary expressions and function arguments are evaluated in strictly left-to-right order. This is similar to Java but different to C and C++, where the evaluation order is unspecified...
> But even though the order of evaluation is well defined, writing code that depends on it is rarely recommended. Note that dmd currently does not comply with left to right evaluation of function arguments and AssignExpression.
https://dlang.org/spec/expression.html
So while there is a specified order, the reference compiler doesn't guarantee it will be honoured!
With the usual approximations, see <code>std.random.uniform</code> and possibly the source code. The slight nonuniformities here don't influence the results (e.g. they're the same for integers).
I think they do everything people would want in concepts - and the way D implements them is very sane, since the in / out bodies are either compile time processed or runtime checked (possibly in debug modes and not in release ones).
I wish C++ would consider borrowing that little piece of goodness.
I thought it was easy to teach programming in D. The following are examples of how D is seen in academia:
Chuck Allison uses D at Utah Valley University when teaching functional programming.
Carl Sturtivant used D in University of Minnesota and "saw a significant majority of the class inspired and excited in some cases by D itself because of its possibilities and expressiveness".
One of the members of the DLang Silicon Valley meetup group, who is (was?) a professor, told us that "D is always on the table" when considering what language to use when teaching programming concepts. He used contract programming as an example; there is no alternative language to teach that concept.
Ali
In D the purity rules are a lot more relaxed. You can even mutate function parameters (via pointer or ref). You just can't do IO, read from or write to mutable state outside of your function and ofc call other impure functions.
For more info: https://dlang.org/spec/function.html#pure-functions
It uses GC though. Nobody using C++ is going to move to that, people that are fine with GC languages have many other more popular options to choose from.
Doesn't help that basically all their points about why GC is great are wrong or at least highly misleading.
You didn't look very hard.
https://dlang.org/areas-of-d-usage.html https://dlang.org/orgs-using-d.html
Probably the biggest recent success story with D is Weka.io: https://www.theregister.co.uk/2017/07/13/wekaio_surfaces_after_swimming_submerged_against_the_current/
And everyone knows about Sociomantic of course.
The closest D comes to pattern matching for expressions would be expression templates, which work as they do in C++. I gave a talk at SDWest a few years ago showing how expression templates could be used to generate at compile time a customized engine implementing a regular expression. I would agree, however, that expression templates are not for the casual programmer.
For pattern matching on types, is expressions (note case 5) can be used. It's a bit wordy, but it works and is simple.
Library solutions were mentioned here by others.
Point being a struct requires you to use braces to statically initialize it. Replace the two lines you suggested by:
Point p1 = {[2, 1]}; Point p2 = {[1, 1]};
More info here: https://dlang.org/spec/struct.html#static_struct_init
Note that above assignment works only in the same module Point is defined because double[2] p is private.
D's standard library supports a similar feature.
import std.stdio; import std.typecons;
void main() { createFile("foo", Yes.Temporary); createFile("foo", No.Temporary); }
void createFile(string name, Flag!"Temporary" temporary) { if(temporary) writeln("creating temporary file"); else writeln("creating permanent file"); }
Inside the function, Yes.X can be treated as true, though it's also possible to explicitly write if(temporary == Yes.Temporary).
Usually i don't announce in this sub but this new release should rather be a good companion to people willing to learn D a bit during this summer. Once DMD installed, setup the IDE and it works out of the box.
I think they're aware of this shortcoming and have been working on it lately. The goal is to remove allocations and make the library range-based so that it generates.. whatever it is we want it to generate lazily. An example of this is splitLines, which returns an array of lines, and its lazy cousin lineSplitter.
People running "mainstream" Linux distributions like Ubuntu or RHEL have definitely come to expect software vendors to maintain up-to-date repositories. Even relatively small software distributions like Haskell Stack and D have APT servers.
That's not what I mean, I know about that. I mean there's no easy way to see this in the std documentation. There should be flags or some sort of visual identifier telling me whether any function is GC or not.
Like here https://dlang.org/phobos/std_algorithm.html there's no way for anyone looking at this to know whether any of it uses GC or not but to simply just compile under @nogc. That's a very bad user experience.
> In Windows, which is mostly C++, they use C interfaces to isolate these ABI incompatibilities, which is probably rather tedious, I'd imagine.
My (limited) understanding is that's usually how C++ libraries provide any sort of interopability with other languages, because C++ name-mangling and function-calling conventions make most anything else impossible.
The D language, which is aimed at being a better C++ alternative, describes the issue as well as how they deal with it. The solutions it lists as the usual choices are "use COM for Windows", "write a C wrapper", "write a tool that writes the C wrapper for you", "rewrite it in something that isn't C++", and "give up".
Not every language could get away with doing it the way D did, but their solution was to attempt to match C++ name-mangling, function calling, and virtual function table layouts as a way to get most of the way there without having to basically build a C++ compiler. Since it knows the mangling rules and whatnot, you can do extern (C++)
and the D compiler figures out how to call it properly. Clever trick, but presumably not viable for most languages or it'd be more widespread.
Speaking of clever tricks, there's also a thing for Gtk called gtk-server that lets you call and use a lot of Gtk stuff without actually needing bindings. It works by being its own binary that you can run and then feed commands to in various ways (named pipe, message queue, stdin, tcp or udp), which means you can use gtk with almost anything, though it's intended as a way to build GUIs via scripting languages. Works with Gtk or Xforms, but unfortunately the idea can't work with Qt for the same reasons that C++ bindings are hard :/
Nope. It's a view from the original array. Not a copy. Not being a copy, allow to save time and wasting RAM. If a copy it's desired, then a method like clone() or copy(), or a copy constructor should be called with the slice.
Like this:
var list = Arrays.asList({"Hello", "Doctor", "Name", "Continue", "Yesterday", "Tomorrow"}); var copyFromSlice = new List<>(list[0..3]);
Look at https://dlang.org/articles/d-array-article.html#introducing-slices
I've done some research on D, because I want to know more programming languages.
All I can say? These two pages (link1 link2) were written by hypocrites.
"Alias is a much more flexible than the single purpose using declaration. Alias can be used to rename symbols, refer to
template members, refer to nested class types, etc."
All of these things can ALSO be done with using
.
And there are still plenty of WTFs in there!
It's probably quite a fine language, but I've never gotten around to learning it because of THAT.
You should check out D. https://dlang.org
They're an active community of people rallying around making a new better C with none of the BS of C++. The developers are receptive to the community and have decided mostly to take it slow and not implement something unless they have a solid solution.
It acquired much syntax from higher level languages to abstract concepts while still maintaining C's efficiency.
D has true immutablity as well with waaaaaaay better metaprogramming to address complex typing issues that arise in C++.
I would recommend against mixing packages, as it will complicate any debugging on imports or make it harder to switch things out later on.
But otherwise the D style guidelines has no opinion on it. https://dlang.org/dstyle.html#phobos_imports
> A small 2D-basebuilder game, with ideas from Factorio/Dwarf Fortress. But more on a hobby level.
I'll bet the bank that you really, really, really don't need to worry about @nogc
for that. Just be smart about how and when you allocate just as you would in C or C++ and make use of the tools D provides if you profiling shows you GC is a problem. Please read the GC series at the D blog: https://dlang.org/blog/the-gc-series/.
No, D's Fibers are stackful, and so not really comparable to C++ coroutines.
I was thinking more of Rust's Generators, which are stackless (like C++ coroutines) but aren't inherently type-erased, so they each have their own type and don't have virtual call overhead (unlike C++ coroutines, but just like C++ lambdas).
> Okay what about https://dlang.org/orgs-using-d.html - 11 of those organizations are hiring. You're incredibly ignorant if you thought that was the only job I could find.
Did you even bother to click any of those links? Half of them lead are dead 404 pages. I did go look through the companies new job listing pages, none of them mention D for the broken links. The one's where the links worked, there were no job postings for D. Seems like quite a few of the companies there also switched to other languages.
Don't link to something to try and prove your point and call me ignorant when you didn't even check if there were actually any job postings. Something tells me that page hasn't been updated in years. It still links to a 2013 article for Facebook. Facebook probably isn't using D anymore like some of the other companies on that page.
> but to say there are none is incredibly dense.
I didn't say there were none (that was someone else), but relatively speaking, there is closer to none than there are to even a relatively new languages like Rust and Go.
> I even work with D.
Then you most definitely have a bias.
You can disable it and run it only when you choose to manually.
You can also statically verify that a given piece of code does not allocate memory from the GC, and thus never triggers it because the only time the D GC will run is when either:
a) you tell it to with <code>GC.collect()</code> or
b) you allocate memory with it (via new
, or concatenate builtin arrays or insert members into builtin associative arrays or throw exceptions or create closures whose captured variables need to survive beyond the scope they were created in. I think thats it, anyway it will error if you try to allocate with it).
For the most part it is a HUGE productivity boon.
D does support that migration route very well: https://dlang.org/blog/the-d-and-c-series/. It is a pity that your evaluation didn't reach this point. This link appears at the top of the D blog; should it be moved to somewhere even more prominent? Or did you find it but still found D's C interop lacking in some way?
you mean interoperation? but actually, no, it looks like the docs are a bit out of date https://dlang.org/spec/cpp_interface.html#cpp-namespaces
That still gives you 80% of the view though, so better than nothing.
I think TaskPool from std.parallelism does that: https://dlang.org/phobos/std_parallelism.html#.TaskPool
> This class encapsulates a task queue and a set of worker threads. Its purpose is to efficiently map a large number of Tasks onto a smaller number of threads.
You should look at D's slices and what the advantages and disadvantages are there. Slices consist of two data structures and that might not be "low-level enough"?
The data itself is an array prefixed with its length, which enables boundary checking and thus safety. I would strongly recommend implicit boundary checking even if it costs some bytes and checking overhead. The additional safety and security is worth it. In other words, prefer Pascal strings over C strings.
On top of that array is a structure which consists of a length and reference to the array. This is two words and can be passed around by value. The length in addition to the length prefix enables some nice tricks like substring without copy. Also, reserve a bit somewhere to mark it as a read-only slice. This structure on top gives you very efficient string comparison but is more complex.
In D slices are mutable (unless marked const) which can lead to confusing behavior. For example, if you pass a slice to some function which changes the data, this might or might not change the original slice depending on its length.
A string in D is a slice of const chars where a char is an UTF8 code unit. There are also slices of bytes. Do you want to handle Unicode? Then go down the rabbit hole of code points, code units, graphemes, and grapheme clusters.
edit: u/vqrs is right. Thanks.
This might be interesting to look at - D's integration with Objective-C. I believe it went through a few iterations as a library, before becoming part of the language itself.
> you're bringing another language on a C++ related thread
Since a number of features of D have found their way into C++ since C++98, I felt it was apropos.
> Why are you importing stuff right in the middle of the function?
It's a common technique in D programming, the idea is to minimize the scope of all symbols in use.
> instead of simply if(T == enum)?
The <code>is</code> expressions can do a lot more than just equality.
> in easier ways than looping
A fair point. The __traits is a general purpose tool in D, not something specifically created for enums. It's used for all kinds of unanticipated purposes. One could also use the metaprogramming capabilities of D to turn that loop into a switch, which would be efficient at runtime, without changing the core language. The idea is that with adequate metaprogramming and introspection features, core language features are less necessary.
> assert(0);
If that is reached, that means the value was not one of the valid values of that enum, which presumably would be a programming bug.
Your best answer will come from browsing the docs and seeing how easily you find things you want:
https://dlang.org/phobos/index.html
If you really want my subjective opinion: yes, I used to feel the pain of C++'s standard library, and it's a major reason I prefer D.
D's standard library isn't as good as Python's, yet --- but "yet" is the key word. Containers are a big gap, but otherwise it's much more "batteries included" than C++'s.
> Stuff like reading individual keys like hot-keys or interacting with the filesystem (creating/deleting files and directories)
Basic file manipulation is there. Reading hot keys is something I'd do with a GUI library or something like SDL (same as with most cross-platform languages).
Python actually has strong typing, and you can in fact do what you did in your example. Even statically compiled languages can deal with arbitrary JSON without needing schema definitions. I recently used some JSON in a D program and it was perfectly pleasant.
I think that's pretty much how the D language came about: https://dlang.org/. From Wikipedia, "Though it originated as a re-engineering of C++, D is a distinct language, having redesigned some core C++ features while also taking inspiration from other languages, notably Java, Python, Ruby, C#, and Eiffel." https://en.wikipedia.org/wiki/D_(programming_language)
The visitor pattern is a solution where there are no better choices. At DConf 2018, Jean-Louis Leroy showed us how he uses D's power to implement open methods as a library solution:
https://youtu.be/MpwHeE2Vvfw?t=640
The beginning of the video shows how inferior the visitor pattern and other methods are compared to open methods.
Ali
I'll throw in for my personal favorite, bearlibterminal
for the graphics library and D for the language. D is like C with classes and some high-level concepts thrown in (real strings! mixins! compile time functions! -betterC
!) that make it a great successor to C.
D's VSCode support is great with webfreak's extensions and /u/Elronnd has written a good wrapper for blt. I use VSCode on Antergos GNU/Linux for working on my D projects, including my roguelike Derelict.
> The article itself states that go was a replacement for c/c++.
The thing is, Java mostly took over from C++ for developing services. (And not many services are written in C these days, except in the embedded space.) Sure, Java eats way too much memory, but it's better than Python and the other dynamically typed languages. Java was pretty much the worst of its class circa 2007, and it was still good enough to be better than C++ in this space.
So is Go better than Java? Well, in terms of memory usage, yes. In terms of application startup time, yes, but only because Java programs tend to use a ton of reflection on startup; a Java program structured similarly to a Go program would only suffer a few dozen milliseconds in comparison to Go.
Is Go better than D, which some people in Google were advocating for instead and predates Go by nearly a decade? Nowhere close. D has some idiosyncrasies from age, unsurprisingly, and the ecosystem's kind of sucky, but Go had no ecosystem when Google started developing it.
Google could have started with C# and altered strings to be UTF-8 and to reuse memory as an alternative. A solid language that was well thought of, and that would have done a lot to reduce memory waste. And if compiling to native code was an explicit goal, well, Mono had supported ahead-of-time compilation for several years by the time Rob Pike started thinking about Go.
Instead, we have an interesting attempt to evolve C into an acceptable applications development language that ultimately failed on its merits and succeeded wildly (for a new programming language) based on corporate support.
Other examples of useful D compile-time compilers:
Compile-time HTML templates: http://vibed.org/templates/diet
Regex compiler in the standard library: https://dlang.org/phobos/std_regex.html#ctRegex
D is a programming language, quote from it's website:
> D is a general-purpose programming language with static typing, systems-level access, and C-like syntax. With the D Programming Language, write fast, read fast, and run fast.
> Fast code, fast.
Dlang is just a query-friendly name for it, I suppose.
Yes, it's the first language I saw that introduced the concept. Although it calls it a scope guard, e.g.scope(exit)
, but it has to include two other forms (because it also has exceptions):
Purity requires analyzing everything a function does, directly or indirectly. We can create a recursive definition: a function is pure if it only calls pure functions, does not reference external mutable state aside from its inputs, and does not modify external mutable state.
You are adding a function to the call graph of doubleA
that is not pure, and the result is something that is not pure.
If I convert the example to D, which can enforce purity and is far less dynamic:
auto doubleA(T)(T a) pure { return 2 * a; } struct O { double toDouble() pure { return std.random.uniform(0, 1); } alias toDouble this; } doubleA(O());
It produces the error: pruity.d(8): Error: pure function 'pruity.O.toDouble' cannot call impure function 'std.random.uniform'
uniform
isn't pure, so pure functions can't call it. Why isn't it pure? Because it references global state. Why does it reference global state? So it can return a different value each time. It's got a seed that it mutates on each invocation.
We could resolve this by not marking toDouble
as pure. However, that gives us a similar error: pruity.d(4): Error: pure function 'pruity.doubleA!(O).doubleA' cannot call impure function 'pruity.O.toDouble'
. We could in turn resolve that by not marking doubleA
as pure -- but then it isn't pure. (Except it's a template, so the compiler will infer purity when applicable -- so not in this case.)
The moral of the story is that, in Javascript, you can't call any function pure that references its arguments. You can call it provisionally pure and come up with a set of restrictions on its inputs that would make it pure.
Yeah, but libc doesn't make use of templates, callbacks, etc. and it also doesn't have a garbage collector that takes control of your program. You always call it, and not the other way around. (Well, there are exceptions like atexit
, but those are explicit) Point being, it doesn't create dependency cycles. As for how you link dynamically to Phobos (and the GC): https://dlang.org/dll-linux.html#dso7
Hello everyone, I am still getting used to Rust and I have 3 beginner level questions. Using higher-order functions, how would you create:
Looks like the answer is "yes":
> If a derived class overrides a base class member function with diferrent FunctionAttributes, the missing attributes will be automatically compensated by the compiler.
Yeah, I was thinking the same reading it.
Checkout D's bitmanip too: https://dlang.org/phobos/std_bitmanip.html
Surely something like the above could be implemented in Rust? D's bitmanip uses compile time magic in the background to create all the parsing code - so, I guess Macros? Not sure of Rusts compile time capabilities tbh.
You might want to check out libmir. Also, you can always use the C standard library through core.stdc
If you're looking for something comprehensive and feature rich like the .Net Framework, you're probably not going to find it. You'll have to piece together something from various sources.
What specific features are you looking for?
While it does not directly address your question, The D Style document does provide some guidance from which you may find some direction.
There are also some identifiers which you should avoid. Though not enforced, identifiers beginning with __
are reserved for compiler-generated identifiers, and identifiers beginning with _d_
are reserved for symbols implemented in the runtime.
The D Runtime Library also has bindings to the C Standard Library at core.stdc which you can use as a model.
If you want a slightly more robust, yet still simple, language that's essentially acting as an improved version of C with proper templates and metaprogramming, D has a stripped-down mode literally called "better C" which outright disables most of those fancy-pants extraneous features like a somewhat more sensible means of error handling (exceptions), OOP with inheritance and interfaces, memory management that doesn't make you want to drink, and a batteries-included std lib.
Although I'm not sure why you'd want to do that when you have the option of using a language with more features to make life easier.
D's debug conditional compilation provides a core language construct. The main motivation for this was the problem many managers told me that every project invented their own debug macro scheme, making it difficult to share code.
The D debug statement, being known to the compiler, enables some semantic goodness unavailable to a template/macro scheme. For example, debug statements often do I/O. But I/O isn't allowed in functions labelled pure
. So D doesn't check what's in a debug statement for purity.
This link is probably better. The important stuff is buried in the changelog. It describes the initial implementation of D's ownership and borrowing system.
Also relevant is this blog post by Walter. Nine months have passed, so I'm not sure how much has changed since that post.
@nogc
options where it can (e.g., a function that allocates a buffer will provide an alternative that takes a buffer as an argument). But really (and this is my own opinion), the fact that it is there shouldn't be a reason to avoid D. You can write a range of programs without worrying about it. When it does become an issue, you have strategies to minimize its impact. WekaIO uses D for the world's fastest filesystem. They can't use the GC. Unless you're doing something on that scale, it isn't going to be a problem. Most of the time, you use the same strategy you would use in C or C++: preallocate as much as you can upfront, avoid allocations in hot loops. The GC series on the D blog has some tips.