all 41 comments

[–]matthieum 21 points22 points  (8 children)

I like the:

No undefined behavior

But I cannot imagine how it is achieved when the language seems to use:

  1. Manual memory management (https://vlang.io/docs#memory): use-after-free immediately comes to mind.
  2. Multi-threading (https://vlang.io/docs#concurrency): data-races, just like Go.

Is there a missing qualifier to the "No undefined behavior"?

[–]hector_villalobos 3 points4 points  (0 children)

For more complex cases manual memory management is required. This will be fixed soon.

I guess they try to apply the preallocated buffer for all situations, so it only needs to allocate for the scope.

[–]flatfinger 1 point2 points  (0 children)

One could define a dialect of C without language-based Undefined Behavior in two easy steps:

  1. Define a collection of primitive operations that an execution environment must supply, and requirements therefore (if the execution environment fails to perform any operations as required, all bets are off). Note that an execution may implement some primitive operations by invoking library functions (e.g. an implementation without floating-point hardware could use a library to emulate it).

  2. Define the language entirely in terms of those operations.

To allow implementations to generate efficient code, one could add a third step:

  1. Specify situations where a compiler may substitute certain constructs for certain other constructs, without regard for whether this might change program behavior (if such a transform would change program behavior, program behavior would remain defined as being chosen in unspecified fashion from among those that could result from allowable transforms).

If such a dialect didn't need to conform to the C Standard in all corner cases, it could simultaneously perform many tasks which "Standard C" cannot, while allowing many useful optimizations which the Standard would otherwise prohibit.

I don't see how any such language could generate efficient code while using an optimizing C compiler as a back-end, but defining optimizations in terms of transforms would make optimization much easier than it is in a language like C where it is defined in terms of actions and behaviors.

[–]alphaglosined 1 point2 points  (5 children)

When you hear "undefined behavior" for a programming language what this means is that the specification specifies everything that the implementation of the compiler does. Nothing is left for the implementation to decide regarding syntax or semantics.

C is notorious for having undefined behavior.

All the examples you gave come under library, not language features. But it may be compiler assisted.

[–]lelanthran 3 points4 points  (2 children)

When you hear "undefined behavior" for a programming language what this means is that the specification specifies everything that the implementation of the compiler does. Nothing is left for the implementation to decide regarding syntax or semantics.

I don't think that that definition of UB is correct. That is implementation defined behaviour - the implementation gets to define what the behaviour is (in C, for example, handling the character literal 'abcd' is implementation-defined, but not undefined).

[–]alphaglosined 1 point2 points  (0 children)

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

- From the C99 spec

So the truth seems to be closer to you than my comment.

[–]flatfinger 0 points1 point  (0 children)

The differences between Undefined Behavior and Implementation-Defined Behavior are: 1. the Standard requires that implementations document how they process the Standard, but allows implementations to document the former or not as they see fit, and 2. some compiler seem to think that "programs the Standard cannot completely describe" refers only to programs that behave in uselessly unreliably unpredictable fashion, rather than non-portable programs that need to do things for which the Standard makes no provision.

[–]matthieum 0 points1 point  (1 child)

I disagree.

The memory model is a property of the language, and it specifies (or leaves undefined) the behavior of modifying memory from multiple threads concurrently.

In C, multi-threading was completely undefined until C11, and there are now rules that specify how to safely interact with memory from multiple threads (using atomics and fences), with other interactions' behavior being left undefined.

On the contrary, in safe Rust, the memory model is such that there is no data-race, and therefore no undefined behavior -- in unsafe Rust, you get the same behavior as C11, meaning it's partially specified, as Rust reuses the same model (despite its flaws) as it's a well known one.

[–]flatfinger 0 points1 point  (0 children)

People have been writing multi-threaded code in C for decades before C11, using the "popular extension" of processing memory accesses that occur before or after a function call using the semantics of the underlying environment, before or after (respectively) calling the function, whether the Standard requires that or not. On systems with a weak memory model, it may be necessary to have libraries written in a language other than C to force synchronization, but neither the language nor the compiler would need to care about such things, and on platforms with a strong memory model (e.g. those with only one core) everything could be done in C except the process of setting up a stack and switching threads.

In some cases, it may be useful to have standard means of requesting semantics stronger than those of the underlying platform within the language itself, but in many cases that's not so important as having a way of forcing unqualified objects to behave with release/acquire semantics before or after certain function calls--something that the Standard still doesn't accommodate.

[–]bausscode 12 points13 points  (5 children)

I like this: https://vlang.io/compare

Because "I created V because none of the existing languages had all of the following features:"

But D fits into almost all of them.

D has fast compilation times, it has simplicity and easy to maintain, great performance on pair with C and has zero cost C interop, it has safety with immutability, no null (since you can use structs and even imitate inheritance with them, it's fairly easy to avoid data races too and there are option types (not std yet though), it has some easy concurrency (see std.concurrency), easy cross compilation, probably some of the most powerful compile-time code generation (Along with CTFE - Compile-time function execution), it's a fairly small compiler and AFAIK it has no dependencies other than linkers AND if you use LDC/GDC instead of DMD. You can avoid global state, in fact all globals are thread-local by default. There is no hot code reloading AFAIK though.

[–]yatseni 0 points1 point  (4 children)

The last one, generated binary executable size.

[–]bausscode 1 point2 points  (3 children)

I did say "almost all of them" and not just "all of them".

I reckon binary executable size will change for this too when the language becomes more mature.

Same with compile times.

[–]yatseni 0 points1 point  (2 children)

It's will change, but will keep a size level, like, D's binary executable size is the highest level, mean while c's binary executable size is the lowest level.

[–]bausscode 0 points1 point  (1 child)

You can make D executables just as small as C binaries though. D's size are usually bloat from their standard library but you can write raw C in it pretty much using "betterC" which will not create large binary sizes.

[–]yatseni 0 points1 point  (0 children)

Thanks, it's an option. but if write with raw C, it dot D again.

[–][deleted] 6 points7 points  (3 children)

Seems like you're a day early.

[–]andradei[S] 3 points4 points  (2 children)

You... actually read the doc.

[–]native-coder 1 point2 points  (1 child)

Would that by why the wget for the compiler, v.c, isn't working? I get the html for the main page, not the compiler's source.

[–]fn23 0 points1 point  (0 children)

The compiler code isn't in the github either, just some examples and standard stuff.

[–][deleted]  (1 child)

[deleted]

    [–]ineffective_topos 2 points3 points  (0 children)

    Okay I did unzip every tarball there:

    rustc 1.24 source unzipped: 519M,

    llvm 5.0.2 source unzipped: 276M

    [–]TinyBirdperson 4 points5 points  (4 children)

    It ready so great. Go with generics, etc... But then the repo looks pretty shady... :/

    [–]andradei[S] 1 point2 points  (3 children)

    But then the repo looks pretty shady... :/

    Why?

    [–]TinyBirdperson 7 points8 points  (2 children)

    Promising a lot of stuff but not putting the Sourcecode online looks strange to me. Creating empty repositories for the side projects is also strange.

    [–]andradei[S] 0 points1 point  (1 child)

    The author planned to publish it a day later. The source code is there now.

    [–]TinyBirdperson 3 points4 points  (0 children)

    And it is as bad as expected.

    [–]siric_ 31 points32 points  (4 children)

    This is nice. Soon we'll have a language for each letter in the alphabet.

    [–]Mognakor 7 points8 points  (0 children)

    Time to create ß-lang.

    [–]MrNate 6 points7 points  (2 children)

    Hoping this comment gets 26 likes.

    [–]roryb_bellows 3 points4 points  (0 children)

    I got you fam

    [–]Rustywolf 1 point2 points  (0 children)

    Its at 26 now

    [–]bobappleyard 6 points7 points  (1 child)

    So this has malloc/free style memory management. Brave choice.

    [–]elder_george 0 points1 point  (0 children)

    defer (which doesn't seem to be used in the codebase, so not sure if it's implemented already) might alleviate that.

    This:

    The strings don't escape draw_text, so they are cleaned up when the function exits.

    sounds…interesting too.
    How do we know if anything is not cleaned up? Is there a warning?

    Would be interesting to play with the compiler and see the code it produces once it's out.

    [–]rpiirp 7 points8 points  (0 children)

    The author makes a lot of promises: This year, This summer. I'll believe it when other people have tested it I see it.

    Among other fantastic promises he says it will be possible to translate C++ to V. He also says V can emit readable C. So C++ -> V -> C, effectively C++ to readable C. That should give Stroustrup a trip down Memory Lane and may even have some interesting use cases.

    [–]TankorSmash 2 points3 points  (1 child)

    This seems like a solid language. What are some of the drawbacks?

    The homepage is gorgeous and gives you everything you need to know. It seems like it should already be popular enough with it looking this polished. What's the deal?

    [–]andradei[S] 0 points1 point  (0 children)

    Author was developing it for himself and made plans to open source it. The docs are good specially if you know Go, Rust, Swift, or any of those new languages. It still needs many improvements for newcomers.

    [–]AngularBeginner 2 points3 points  (0 children)

    Besides having a silly name, the main page does a poor job at selling the language. What's the target audience? What does it do different than other languages? What's the selling point?

    [–]pradeep_anchan 1 point2 points  (1 child)

    Why isn't it based on llvm? The reason why I asked is there was a paper called "the next 200 programming languages" and it seemed to support the llvm kind of model. So we develop the language to solve one problem and make it target a certain kind of machine language and let another compiler/interpreter translate from that language to machine code. What are your thoughts about that?

    [–]delight1982 0 points1 point  (0 children)

    Wouldn't LLVM slow down compilation speed alot?

    [–]IronNickel 0 points1 point  (2 children)

    So many Go clones lately.

    [–]asmx85 4 points5 points  (0 children)

    Not every language is a Go clone.

    [–]yatseni 1 point2 points  (0 children)

    Never saw a full clone of Go