15 ms·
I tinkered with D a bit (along with Nim, Dart, and C as a comparison) while writing a Clojure interpreter. D seems to be a nice language, but I found the edito
by christophilus 9y ago
I tinkered with D a bit (along with Nim, Dart, and C as a comparison) while writing a Clojure interpreter.
D seems to be a nice language, but I found the editor integration wasn't the best. I also found it annoying that the docs used `auto` all the time, so you could never figure out the right type annotations for their APIs (e.g. I want to call the foo API and return its value from my method, but the docs all use `auto` to refer to its return value, so I don't know how to annotate my method.)
I liked Nim better in almost every way but one: the compiler was fickle and would just fail silently sometimes.
- logicallee 9y ago>Nim, Dart, and C as a comparison) Could I ask about your thoughts regarding Go (which has much less syntax and fewer features than all of the above). Have you looked into it?
- christophilus 9y agoYeah. It should have been in that list, actually. I wanted to like Go. It seems simple (which is what I like so much about Clojure), but honestly, I found it to be frustrating for all the standard reasons the Go team is tired of hearing (e.g. no generics, error handling littering my code and obscuring intent, etc). In fact, I think Go doesn't quite deserve the reputation it has as being a simple language. It's a familiar language, and it's a bare-bones language, but that's not the same thing as being simple. One last thing that was interesting: I got more null pointer runtime exceptions in Go than I expected (vs none in Nim, for example). Granted, I'm a Go n00b, but I'm also a Nim and Dart n00b, and didn't have nearly as much trouble with those two languages (aside from the aforementioned compiler bugs). I really wish modern statically typed languages would rid us of null pointer errors once and for all. This is totally possible with Option types, but seems to rarely be done. I wonder why?
- lambda 9y agoHave you looked at Rust? It uses Option types, has generics, also uses return values for error handling but has a lot more syntactic sugar to make it cleaner than in Go.
- christophilus 9y agoI have tried Rust in the past, though not on this particular hobby project (my Clojure interpreter). I found it hard to get into, and I've gotten into a lot of languages in my time-- some of which are considered challenging (e.g. Haskell). With Rust, I always felt I spent too much time wrestling with it, and not enough time being productive. I imagine that you hit a threshold at some point and that begins to change. But for my side projects, that bar wasn't worth jumping.
- steveklabnik 9y agoRust's major goals this year are around learnability and productivity; maybe come check it out again someday :)
- theprotocol 9y agoCould you point to any materials (e.g. blog post, roadmap document...) that deal with this? Thanks.
- steveklabnik 9y agohttps://blog.rust-lang.org/2017/07/05/Rust-Roadmap-Update.html https://blog.rust-lang.org/2017/07/05/Rust-Roadmap-Update.ht... is our "the year is half over" update, and has a link to the overall goals right at the top.
- theprotocol 9y agoAwesome, thanks!
- 9y ago
- logicallee 9y agoEDIT: this is getting downvotes for some reason even though it's just addressed to OP. OP, you could email me at the link on my profile if you didn't want to answer here. I'm not on the Go team or anything, just curious. --- Thanks for your answers! So I know you don't want to rehash what's easy to find elsewhere, but your perspective is different because you wrote a Clojure interpreter. It's not the same as what I can find from people who just use languages. You just list: >(e.g. no generics, error handling littering my code and obscuring intent, etc). But could you flesh out this litany of complaints, even if it's common? I just want to know your version of that list, without the 'etc'. It's not going to be the same as other people's - different things will bother you or come to mind for you. I'm trying to understand these from your perspective and background. (which is unusual.) Secondly, you write "but that's not the same thing as being simple". I don't really understand. Here on HN, people say you can pick up Go in an "afternoon" and become proficient in "a week". You write that it is not simple but I don't know what you mean in specific, even when you write as a "Go n00b". This reply will be particularly interesting to me, because, since you've literally written an interpreter, compared to an average user, everything is simple for you. Like, think of a standard designer who has first dabbled in Javascript and for some reason picks up Go. Whatever isn't "simple" for them would ordinarily be super-simple for you. So what's not "simple" for you is like obscure string physics to a person who is barely a programmer at all. I'm really curious what parts you didn't find simple. Thank you.
- cstrahan 9y agoI'll let the parent answer you (though I have similar sentiments as someone with language implementation experience, and FWIW, I have professional experience with Go, Ruby, JavaScript, Clojure, C#, and I've used Haskell, F#, and much more in my free time). I will, however, point out that you're likely using a different definition of simple ("easily understood or done; presenting no difficulty. ") than is often used in technical circles ("composed of a single element; not compound"). Simplicity and ease are distinct, and one does not necessarily imply the other; it's not hard to find convoluted designs that feel easy due to familiarity, while a much smaller, consistent design will feel difficult because the concepts (while fewer in number) are foreign. Rich Hickey (creator of Clojure) gave a great talk on easy vs simple: https://www.youtube.com/watch?v=rI8tNMsozo0 https://www.youtube.com/watch?v=rI8tNMsozo0 Here's something familiar to most professional web developers: JavaScript. But it's also complicated: https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat Here's the spec: https://www.ecma-international.org/ecma-262/8.0/index.html https://www.ecma-international.org/ecma-262/8.0/index.html And here's something unfamiliar and often considered difficult: lambda calculus. And yet it's very simple. Here's the entire definition of lambda expressions (lifted from Wikipedia): --- Lambda expressions are composed of: * variables v1, v2, ..., vn, ... * the abstraction symbols lambda 'λ' and dot '.' * parentheses ( ) The set of lambda expressions, Λ, can be defined inductively: 1. If x is a variable, then x ∈ Λ 2. If x is a variable and M ∈ Λ, then (λx.M) ∈ Λ 3. If M, N ∈ Λ, then (M N) ∈ Λ Instances of rule 2 are known as abstractions and instances of rule 3 are known as applications. --- So, while JavaScript programmers might find the lambda calculus unapproachable, it would be difficult to argue that the former has fewer gotchas than the latter, as the former is wildly complicated and the latter is so simple that you could fit its definition on business card. Once you appreciate the difference between simplicity and ease you can better evaluate your options, as it might be worth investing time in learning an intimidating, foreign solution if you believe that it will provide better stability/correctness guarantees/etc. Also, simple things are generally easier to work with compared to complex things assuming a similar degree of experience -- so investing in unfamiliar-yet-simple things will often save you a lot of effort in the long run. Strictly adhering to familiar things is a recipe for being stuck in a local optimum. To take this full circle, Go being easy doesn't mean that it's simple.
- TylerE 9y agoI sometimes feel Go went to far, as in the classic quote "Make it as simple as possible, but no simpler".
- logicallee 9y agoI understand what you mean by your quote. I will give you a toy example, then show the single example I have from Go, and ask if you know of any more. Toy example, a language that is simpler than possible: - If a language does not have functions, you must copy and paste the code every time you call it. Such a language would be "simpler than possible". The only example I know from Go: - Many people feel that the lack of generic functions can be solved similarly - such as copying and pasting code or doing search/replace - but makes the language "simpler than possible". (in the exact sense you mean.) (A generic function is one that works on different types without knowing what they are when it is written, or similar behavior.) So I've given you a single real example. But it's the only one I can think of. Other than this example, can you list the ways in which you feel it's "simpler than possible" or went "too far"? I would really appreciate if you could be specific.
- omaranto 9y agoI'll repeat my usual comment about what I found annoying in Go: It seems like strings are basically the only data type of unlimited size that is supported as map keys (or at least that seemed to be the case a few years ago). I think that only types for which equality is defined in the language could be used as keys. Those types where numbers, characters and all other "small" fixed-size types, structs all of those members had equality defined, arrays of a type with equality, and strings. The size of an array is part of the type, so in that list of types with equality the only source of unlimited sizedness are strings. I guess that cover most cases where you want a type of unknown size as a key, but I found it pretty annoying. If you want to use, say, polynomials with integer coefficients as keys in a map, you'd have to either choose a fixed maximum size (degree, for example, or number of monomials) for the polynomials or convert back and forth between strings. It's not the only language that forces you to convert things to strings and back for use as map keys (AWK and Lua come to mind), but I wish it didn't have that limitation.
- mhh__ 9y agoThe D standard library is generally designed to generic code: you often aren't supposed to see the type returned by a function. Also, you can use auto too + Template constraints would help you here.
- christophilus 9y agoI understand. That's why I mention it as one of the downsides of D. It's probably subjective, but I like to see the types of function signatures. It serves as documentation, and makes it easier for me to say, "What does this function return, and what can I do with it?"
- ben-schaaf 9y agoThe problem is, with a lot of the range code in D you can't actually specify the return type since it's an internal struct or similar. Seeing MapResult!R map(R, alias fn)(R range) makes it seem like MapResult is a thing you can reference/use. But it's an internal struct, so it's neither accessible not documented. That's a whole lot more confusing than having auto and documenting that the result is an input range.
- skymuse 9y agoIdk about the editor integration problem, but usually when I run into the 'auto' problem what helps me is printing out the type as follows: typeof(var).stringof.writeln;
- WalterBright 9y agoThere's some debate about where is the sweet spot in the use of `auto` between self documentation and minimizing refactoring costs. Fortunately, the programmer gets to decide which to use.
- wtetzner 9y agoIt sounds like OP's issue isn't that auto exists or that people write code using it, it's that the documentation uses auto, which makes it hard to figure out the types of things when you look them up.
- yorwba 9y agoThat could be solved by turning function calls in example code into hyperlinks to the relevant documentation, which is a good idea in general.
- christophilus 9y agoOP here. Yes, that would be very helpful.
- zombinedev 9y agoCan you compare your D vs Nim experience in more detail? What are the key points that you like better about Nim?
- dom96 9y ago(Disclaimer: one of the Nim core devs here) Happy to see you paint Nim in a (sort of) positive light, I hope I can help with this one negative. > I liked Nim better in almost every way but one: the compiler was fickle and would just fail silently sometimes. Can you give some examples and elaborate on what you mean by "fail silently"? Did you at least get a segfault?
- christophilus 9y agoUnfortunately, I don't have any examples off-hand. It was a month ago. I'll see if I can dig the repo back up and reproduce the error. As for how it failed, it did not segfault. It just stopped and dumped me back out on the terminal with no output at all. (I'm on OSX 10.12.6.)
- dom96 9y agoThat's a pity. Let me know if you dig it up. Next time please create an issue on GitHub[1], you don't have to worry about creating a small example either, as long as you give us all the code to compile it. 1 - https://github.com/nim-lang/nim https://github.com/nim-lang/nim
- christophilus 9y agoHey. I appreciate you showing this level of concern. I'll track down that project and open a few issues if I can reproduce it... It may not be until next week, due to traveling and other things coming up.
- christophilus 9y agoI tracked down the repo and wasn't able to get it to bomb on me as before. I honestly can't remember what scenarios triggered that, unfortunately, and I'm no longer working on the project (due to actually being back at the 9-5 job!).
- dom96 9y agoThank you for taking a look. Maybe the problem was already fixed :) If you do find anything else then do post it on GitHub, or at least let us know on IRC/Gitter.