GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together. Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account. Indeed, perhaps we need an abstraction that provides a vtable of some kind.
Traits seem pretty reasonable. I still need to think it all over before deciding on a particular abstraction. One thing I want to do before closing this issue is create a GUI application with widgets and stuff. That's the classic use case for OOP so we can test out how well the vtable abstraction works. It looks like if you allow fields to be reordered by the compiler, then this would not be possible.
That will prevent a certain kind of polymorphism from working. This is fine as long as it is explicitly stated somewhere. See the points in issue OK, so that would not work if for some reason the compiler could reorder fields it might work, but it would not be guaranteed. C lets you cast and guarantees that the order of the fields in the struct definition is the order in memory.
So, in C, this always works. I tried to cover this use case in issue Please consider taking inspiration from Golang's interfaces.
They greatly help with making code easy to write and understand. Writer by default. Go's interfaces aren't the best way to do things.
Structural typing seems to go against the Zen of Zig. In my opinion, zig's metaprogramming features are strong enough that this can reasonably be written as a library feature. This implementation pretty much works like Rust traits, the interface struct either owns or points to the implementation object and the vtable pointer and the vtables are generated at compile time, one time for each new implementation type. Quick thought: having a really tiny feature set is actually a very strong language feature.
Maybe this kind of abstraction should be in a library that can be imported to get extra abstraction macros? Then people can still use the core language without having to understand many features.
This echoes alexnask 's thought above. Huge thank you to tgschultz for working around countless bugs and making the following proof-of-concepts, which demonstrate the userland alternatives to language changes for this key issue:. Being completely honest, I have not reviewed these pull requests yet.We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust.
We should also think of if we can improve unsafe Rust to be harder to misuse.
There are improvements coming in compile time evaluation, and those can potentially make the compiler much stronger when it comes to detecting memory errors in unsafe code at compile time. There's not only a pedagogical task here, but the Rust community must learn how to write code safely.
Writing a small ray tracer in Rust and Zig
The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation. This kind of problem comes up a lot. Composed atomic operations are not atomic.
Composed correct threaded code is not always correct. Enabling different Haskell language extensions gets you off the deep end quickly, and some unsafe combinations are surprising see GeneralizedNewtypeDeriving, which is considered unsafe even though it used to be safe.
Your comment is flatly wrong: users using only safe code are not responsibility for guaranteeing the composed safety of the components they use whether or not they are implemented with unsafe code.Why rust is getting popular
Interfaces marked safe must uphold Rust's safety guarantees, or they are incorrect. Because they cannot depend on untyped invariants, any correct implementation with a safe interface can be composed with any other. This ability to create safe abstractions over unsafe code which extend the reasoning ability of the type system is a fundamental value proposition of Rust. I hate being tone police, but jeez, we're having a discussion about Rust here and talking about my personal competency is inappropriate and unwelcome.
The problem I'm talking about happens when you write libraries that contain "unsafe" blocks. You want to prove or at least assure yourself that no unsafe behavior is observable by clients of the library. However, the way to do this is not entirely clear, although there is research being done in this area.
One known trap is that it is not sufficient to demonstrate that Rust code without "unsafe" blocks cannot observe unsafe behavior in your library. Proving the correctness of unsafe code is totally different from what you talked about, which was composing different abstractions with unsafe internals together.
Users of safe Rust do not need to worry about whether the composition of two safe interfaces that use unsafe internally is safe unless one of those interfaces is incorrect.
Your comment would suggest that users need to think about the untyped invariants of each library they use, but this is not correct, libraries are not allowed to rely on untyped invariants for the correctness of their safe APIs. The problem with talking about this subject is that "safe" and "unsafe" are overloaded terms in Rust, so I can understand why you think I was talking about something different.
Let R be arbitrary Rust code with no "unsafe" blocks. Let X and Y be libraries with "unsafe" blocks. And this is what I mean when I say that this is not only a pedagogical problem. You have restated your position, but it is still incorrect in the context of this discussion. Even your original statement of "R be[ing] arbitrary Rust code with no 'unsafe' blocks" is problematic: any Rust code is, very unavoidably, built upon a foundation of unsafe code. It has to bebecause it's running on an "unsafe" processor.
And yet, any safe Rust code in the core library barring a safeness bug is obviously safely composable with any other safe Rust code precisely because it obeys safety guarantees when transitioning from unsafe to safe. The fact that you can mistakenly conceive of Rust code that somehow avoids any internal unsafety simply reinforces how obvious this simple fact is.WalterBright on Oct 14, One finds themselves debugging their knowledge of the programming language instead of debugging the application itself.
My experience with it, though, is that if the language is too simple, the complexity gets pushed off into the application. The thing about complexity in the language, on the other hand, is once you do learn the language, that skill follows you with every app you work with. With complexity pushed to the app, you have to re-learn it with every app.
A screwdriver can do a lot of things - chisel, hammer, scraper, prybar, punch, paint stirrer, shim, etc. But I prefer having a set of tools designed to be chisels, hammers, etc.
My projects come out a lot nicer. It's an interesting point. This is a frequent complaint I hear about Go: they made the language too simple in certain places. People also tend to cite Rich Hickey's distinction between "simple" and "easy". So the question about Zig becomes one of what exactly was kept simple, and what was allowed to become complex? I think the world would benefit from a Hyperpolyglot-style comparison here. Rosetta Code is too much of a mess; ideally, I want to see a thoughtful side by side comparison of the same program written in several languages, with commentary.
Zig might get away with it by restricting itself to a narrow niche where this kind of simplicity is advantageous. Go tries to eat a much larger piece of the pie, and the deficiency is felt more as a result. There's a profound wisdom to knowing the niche you're in, and Zig does seem to have that.
The applications part of the stack is saturated with options, all trying to encroach on each other, but when it comes to the genuinely low-level, unsexy stuff By cutting out its own metaprogramming functionality, it's much more straightforward to generate useful Zig source.
There are a lot of advantages to restraint in the design, and Go does share that, too. I think many Go developers would consider this a feature I do, anyway. A little boilerplate is better than a complex language. You're obviously familiar with D, but in response to your post defending D's complexity, let me offer a different take.
You are free to ignore a lot of that complexity with D. I don't use most "features" of the language, and in a lot of cases, I don't even know how they work. My code is a lot like C code.
I don't mess with attributes, templates, CTFE, etc. You can use a style in D that is even simpler than Go if you want, but it's nice to have the extra features for the times that they're handy. Just because the features are there doesn't mean it's a good idea to use them - and D allows you to program that way. This attitude is fine for personal projects, but it does not scale when working with other people. Even in a two person project, one person using a language feature will inadvertently force the other person to learn how that feature works.
And they will not even know if the feature was appropriate to use until they have learned it. With this small amount of reasoning we are back to the tired old argument of "Which is better? Ease of expression or ease or learning? Even if true, so what? But honestly, this is one of the worst programming language arguments there is. Any feature can be misused.
Unsafe Zig is Safer than Unsafe Rust
There has to be discipline - full stop. Restricting the language is not the answer because that just leads to worse code, not better.Another example. It's pretty subtle, but there is actually undefined behavior going on here. That's the code for the main function. This is using rustc version 1. Let's zoom in on the problematic parts:. None of these allocaloador store instructions have alignment attributes on them, so they use the ABI alignment of the respective types.
That means the i8 array gets alignment of 1, since the ABI alignment of i8 is 1, and the load and store instructions get alignment 4, since the ABI alignment of i32 is 4. This is undefined behavior:. It's a nasty bug, because besides being an easy mistake to make, on some architectures it will only cause mysterious slowness, while on others it can cause an illegal instruction exception on the CPU. Regardless, it's undefined behavior, and we are professionals, and so we do not accept undefined behavior.
In Zig the problem of alignment is solved completely; the compiler catches all possible alignment issues. In the situation where you need to assert to the compiler that something is more aligned than Zig thinks it is, you can use alignCast. This inserts a cheap safety check in debug mode to make sure the alignment assertion is correct.
Thanks for reading. Can you spot the problem with the code? This is undefined behavior: the store has undefined behavior if the alignment is not set to a value which is at least the size in bytes of the pointee the load has undefined behavior if the alignment is not set to a value which is at least the size in bytes of the pointee It's a nasty bug, because besides being an easy mistake to make, on some architectures it will only cause mysterious slowness, while on others it can cause an illegal instruction exception on the CPU.The table above and the list of the features on the home page should give you a pretty good picture.
It offers up to times faster compilation, safety, lack of undefined behavior, easy concurrency, compile time code generation, etc. Compared to Python, it's much faster, simpler, safer, more maintainable, etc. You can use this formula for any language. Go V is very similar to Go, and these are the things it improves upon: - No global state - No null - No undefined values - No err! It is a complex language with a growing set of features and a steep learning curve. No doubt, once you learn and understand the language, it becomes a very powerful tool for developing safe, fast, and stable software.
But the complexity is still there. V's goal is to allow building maintainable and predictable software. That's why the language is so simple and maybe even boring for some. The good thing is, you can jump into any part of the project and understand what's going on, feel like it was you who wrote it, because the language is simple and there's only one way of doing things.
V compiles 1. Examples Documentation Modules vpm Wasm Playground. It's a simple program that fetches top Hacker News stories concurrently. ReadAll rsp. Body if err! Lock defer mutex. Get url if err! Println story.The two languages that I spent most of my time daydreaming about writing code in are Rust and Zig.
Rust, because of its focus on safety and performance. The language effectively tries to prevent you from shooting yourself in the foot. A few promising graphics libraries, like gfx-rsmake the language very appealing. But on the other hand, the language has a steep learning curve. Additionally, some of the community discussion gives me little hope that the language is going to stop growing anytime soon. At this time, there are already two slightly different ways of using modules.
Zig, because of its focus on robustness and clarity. The language aims to be easily readable and understandable. But on the other hand, the language lacks lots of features, like operator overloading, interfaces, and traits.
Which language is more enjoyable to use for writing a small, self-contained computer graphics project? To find out, I decided to implement the same simple project in both languages: a small ray tracer, following the book Ray Tracing in One Weekend.
Briefly put, ray tracing is a computer graphics algorithm in which light is simulated by shooting a bunch of rays from the camera into the scene and tracking the path the rays take as they interact with the scene.
To kick the project off, a way to display images is required. I wanted to render the image directly to an open window, instead of outputting the image to an image file, like the book does. So, to start this project off, I had to open a window and display some colored pixels on the screen.
The goal of this section: open a small window and add some colors to the pixel buffer. Of course, you can use SDL in Rust as well. It does one thing well — it lets you open a window and set its pixel buffer.
No complex setup required, perfect! The crate was automatically downloaded and compiled in the background the next time the build was executed. I have to say the discoverability of packages is really nice on websites like crates.
While many packages are not mature, it is nice to see what people have worked on in one place. Zig is a very new language in comparison to Rust. That means no convenient packages to get you started. This made introducing SDL into the project fairly painless. Zig actually goes a step further, because the Zig compiler is also a C compiler.
I wrote a small C function to set pixel values in the window surface in C, and the C source file could be compiled alongside the Zig source, with the following small addition to the build. Rendering images in the ray tracing book involves writing definitions for ray-sphere collision testing as well as writing definitions for how the ray interacts with the surface of a sphere once it collides.
Testing whether my ray-sphere collision tests work: the scene rendered using just the color value of the object. More tests: the scene rendered using the surface normal vector as a color.Tea tree oil is an antibacterial essential oil that can blast the microbes that have started to make a home inside of your pores.
With a dropper, dab a Q-Tip with a bit of tea tree oil and apply to pimples as needed, being careful not to put on too much. Crush up an aspirin tablet and add just enough water to make it into a paste. With a Q-Tip, add the aspirin paste to the pimple(s) lightly, covering entirely. Aspirin is another anti-inflammatory, meaning it will help the skin fight against inflammation, making the pimple less visible. Let the aspirin paste fight the pimple overnight. Astringents are agents that cause the skin to contract or get smaller.
Some pharmaceutical astringents contain antimicrobial ingredients that will help fight the pimple in addition to reducing the size of the pimple. Here are some astringents to consider using: WH.
These come in different types and sizes. Look for one that contains benzoyl peroxide or salicylic acid. Ask for astringents that are gentle on the skin. The citric acid here kills the bacteria that cause acne and act as a skin-tightener. Many people swear by it. Slice a lemon and gently rub it over the affected area. Banana peels are helpful in treating insect and mosquito bites, and may be helpful in reducing the size of some pimples.
Gently rub the banana peel over the affected area. Another great astringent with a ton of applications. Look for witch hazel that doesn't contain alcohol. Apply a small bit over affected area and let dry.
Green tea is an astringent that's packed with lots of antioxidants, which help reduce signs of aging by fighting free radicals.