The main thing that I use compiling for is to validate little off-by-one things. Like, is substring() exclusive on the second parameter? What about range syntax and the slice operator? What if I wrote + 1 instead of - 1 somewhere, or did < instead of <=? I could spend a few minutes combing documentation, or just compile it and check immediately. Well, assuming compilation is fast anyways.
I'm a really big fan of reading the docs (or, where the docs are insufficient, the source), and will always have docs.rs open alongside my editor. While the examples you provide are easily validated by testing (and I'd probably use `evalr` in `##rust`, or some similar thing, for them), many subtleties can exist in more complex functions, so not reading the docs/source for unfamiliar functions feels like programming-by-guessing to me.
(OK, you could read preferences from a file, but then you'd have to optimistically write every value you'd ever want to recompile to a file. I've tried this, but it's far too much overhead.)
I'd also recommend getting used to serialisation/deserialisation. Serde for Rust makes this remarkably easy. Writing every setting to a file is simple if the compiler can do it for you, rather than you walking the long way around.
Also there are also a shit-ton of minor logic-changing modifications when you're writing prototype gamedev code, (for example, moving an if statement here or there to tweak the physics of your platforming). These cannot be easily represented in config files, and this is why people attach lightweight scripting languages like Lua to their game engines (so that you don't have to wait for those atrocious C++ compile times when tweaking your gameplay code).
(Ironically, serde is known for its atrocious compile times, which really makes the situation even worse. Because of this some frustrated Rust gamedevs wrote their own serialization libraries such as nanoserde (https://github.com/not-fl3/nanoserde)... but you get the point.)
But I work on network protocols and file formats and parsers and video transformers and user interfaces (often command line or web) and a long time ago games ;P... I make a small change and then I want to see the behavior difference. I almost always type code that compiles, but that doesn't mean it did what I want when interacting over the network: rust doesn't provide anywhere near powerful enough type abstractions to actually prove my code is correct... it only is proving that my code can't crash and will avoid undefined behavior.
What is so frustrating is that there is nothing about Rust that makes it impossible to make fast. With C++ I get to manually make tradeoff in my code on a file-by-file basis with an assumption that my project will be built out of thousands of mostly-independent fragments that I am able to compile incrementally or in parallel. I can very rapidly isolate individual functions I am working on for fast iteration without having to restructure my project, I can tell the compiler to instantiate templates in different ways to reduce dependencies, and I have designed a system to let me do parallel compiles on AWS Lambda (I haven't yet gotten my build environment to be ready for a -j1000 parallel build, but I am somewhat close).
I have been integrating some rust libraries into my codebase (I haven't even gotten to the point of really coding in it omg) and Rust is just so painful and frustrating to work with... and it really does just seem to be, as you pointed out, a matter of priorities and interest: there is this myth that it is some kind of tradeoff on the type system, but it isn't; it is just that the people who work on rust seem to not work on the same kind of projects that we do, at least in the same way, and so have made a bunch of trade offs like "I would rather never have to type a prototype than save any time compiling" and "I would rather my build system never have to consider dependency management than save any time compiling" and "I would rather provide the highest possible quality resulting binary than save any time compiling" (which is at least one I can appreciate, but only once a month when you cut a release... not the hundreds of times a day that I recompile my C++).
Rust outputs prototype information in .rmeta artifacts that are generated as one of the first steps in compilation, so this is not a compile-time issue. AFAICT, dependencies are also tracked, and debug vs. release switches are provided that also control things like binary optimization.
The real "problem" for compile times in Rust is that Rust makes it idiomatic to write code that's slower to compile. That's really all there is to it. If you were to literally write Rust like it's C, you'd find that there's no real overhead introduced by Rust per se.
(This is not to say that improvement is not possible, of course. Even what's "idiomatic" can be tweaked over time to reduce the amount of excessive, duplicated work that the build system has to do. Newer features like const generics will probably make this feasible in the future, and improvements in the compile workflow itself will do the rest.)
I am quite curious how usable Rust/WinRT will turn out to be for WinUI work.
I know exactly what you mean. Front-end development can be this way, too.
I think it's OK (and probably true) to say that you shouldn't use Rust for cases like this right now.
I think that's true, but only because of the slow compile times. Which is why they're so frustrating. Rust would otherwise be an excellent language for these use-cases.
• The Azul GUI toolkit uses CSS for styling of its widgets, and hot-reloads stylesheets.
• The Mun programming language is designed for the sort of niche Lua is often used, with hot-reloading scripting-like functionality to augment your Rust code. (Well, Rust is the main host language at present, anyway.)
Rust has a testing facility that can be used for these things. By default, all "example" code that's included as part of a doc comment ends up in the test suite. And because test cases are small and self-contained, they're also very quick to compile.
I think the main reason why I dislike working with dynamically typed languages is that most of them make the reasoning of code a lot harder. If you're able to reason about the code at hand, then there's a lot less need to run the code for every small change.
Maybe it's time to switch to an interpreter ? :-)
That being said, C# is clever enough to only need to recompile the assemblies affected by your code change, so often you can get away with 10 second compile times even for large solutions.
So you had to work in individual projects at a time, slowly going through and changing stuff project by project.
VS wouldn't even build it either, really. YOu had to build via batch file that did various ms build magic. I would make changes, set of a build and go to lunch, then come back and fix the errors.
Once you checked the code into source control it would trigger a build which would sometimes take upwards of an hour :( I hated that code base.
It got even worse when they added Coded UI tests. Wait an hour for a build and then a random Coded UI test would fail and the advice from the people who wrote the Coded UI was "just run another build!", yeah, flakey tests on a code bases that tests an hour to run...
Only one of them says anything and it an empty statement like
> F#'s compile times also seem to err on the long side but not very much so, my impression goes.
However it is quite easy to validate write the same algorithm in F# and Rust and then compare.
Ah but Rust is AOT compiled, easy, use NGEN, .NET Native, or Mono AOT for the F# compile time measurements.
People should be educated on the huge bias introduced by personalized services like google.
I'd love a REPL that could somehow load the state of my entire app so I could test stuff out, but I've never found a language that could do that and also had reasonable type safety guarantees.
But god it's slow... Some static analysis support would also be hugely appreciated. Not being able to check everything doesn't meen you shouldn't attempt to check something! Many specs are type predicates anyway.
Clojure spec is great at system boundaries but it's hard to describe it is a type system, it's a predicate system it can define very arbitrary constraints mostly at runtime
I can’t imagine not looking up the documentation to do this.
If a language had a REPL I may then confirm it in the REPL, but almost certainly would pull up the docs first.
Definitely a leftover from when I was a kid, in the early 90s, without ready access to computers. I remember lying at a hospital bed and filling pages and pages with C64 programs, using pen and paper.
This kinda forced me into the paradigm of "think through invariants and structure first". To this day, typing code out on a computer (incl. compilation) is almost mechanical, not a vital part of the design process.
I don't think typed vs untyped languages really makes a huge difference if you're designing code this way. The difference comes when the compiler can actually verify your design, if you don't compile it doesn't really matter what the compiler can check.
I mostly work with C#, and occasionally I might only end up compiling the project a couple of times in a day, but I'll probably be building a test project several times in the meantime (e.g. after adding each test).
Alternatively, if I'm building a web GUI, I'll probably be building quite frequently, making sure that data is bound correctly and that the UI looks as expected.
It is easy to let a project slowly slide into a state where this workflow is no longer possible, especially in high-level languages like modern C++ or Rust, when even incremental builds take so long that it throws you out of "flow".
But anyway, I think this sort of working style doesn't have to do with a language's type system, but is a personal choice and one isn't necessarily better than the other, but certain personalities might be attracted to certain language communities, and thus directly influence priorities (e.g. a large part of the 'modern C++' community seems to think that compilation time and good runtime performance in debug builds are not high priorities, which from my point-of-view is entirely irrational).
I also use assertions and unit tests, because the type system still has its limitations (or some things would be too awkward to express), but I can move forward a long way without actually compiling a project.
So, for my workflow relatively fast compile times are mandatory.
(Altough, I really wanna get out of desktop dev.)
I much prefer working from a logical and thoughtful approach rather than iteration. At the point where I start a build I am already reasonably confident that it will do what I want it to.
There are some bugs where I will need to re-build several times consecutively but these are relatively rare for me (I work on REST API systems - so nothing too crazy).