vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.67k stars 2.15k forks source link

Just published the first V example to show you some features of the language. Very interested in your input. #3

Closed medvednikov closed 4 years ago

medvednikov commented 5 years ago

Very interested in your input.

https://github.com/vlang-io/V/blob/master/examples/users.v https://github.com/vlang-io/V/blob/master/examples/hello_world_gui.v https://github.com/vlang-io/V/blob/master/examples/generic_repository.v

ducdetronquito commented 5 years ago

Hi @medvednikov !

My answer will be off-topic: I just wanted to thank you for what you are doing with Volt and V, both look very promising !

I see a huge amount of feature requests, and I just wanted to say: Take your time, good softwares takes time. It's easy to get overwhelmed building Free softwares: sometimes it's better to say "no" or "not for now" in order to build great things in the long run :)

Have a good day !

xorhash commented 5 years ago

Here's an assortment of thoughts:

From a Ruby and C background, I quite appreciate constants having to be uppercase. It also helps grepability (you know that you have to grep 'const CONSTANT_HERE' -r * if you want to find the value of a constant).

You may already want to put special thought into the HTTP library since I assume it will see a lot of usage. In particular, you may want to support both synchronous and asynchronous patterns; consider some standard library way to event loop all kinds of networking.

I enjoy the design of the or keyword and how you can immediately force a return. However, I'm not sure if an implicit $err is always the right solution. I'm worried about localization and internationalization of error messages in particular.

How do you return failure from main? This isn't as much of a concern on Windows and for GUI applications, but your example doesn't seem to address a case like int main(void){return EXIT_FAILURE;} in C. I'm also rather happy about eprintln() existing; you may, however, want to look at the BSD err(3) family, which print a message to stderr and then exit with the given exit status.

I'm not sold on having both ' and " as string delimiters with no semantic change. I know that Python does that, but considering UNIX Shell, Perl and Ruby all consider ' to be special in prohibiting variable expansion, you might want to do the same.

Looking at the printing examples: Is it accurate that a variable identifier can be any character.

What happens if you try to println() an array type? My intuition would suggest that a compilation error would have the least surprise, but you may want to do something else.

What even is an int? Is that a literal C int with all the risks of undefined behavior on signed overflow? Are unsigned types even available? Sun's experience with Spring (the OS from the 90s, not today's Java framework) showed that you kind of need unsigned integers for writing device drivers.

Are you making any guarantees about the C code output of a function that only does arithmetic on integer types and has no branching? This may be relevant for the implementation of cryptographic algorithms in particular.

Concurrency remains an open issue to address in another example, too, probably.

medvednikov commented 5 years ago

Hi @xorhash

Thanks a lot for your detailed feedback!

You may already want to put special thought into the HTTP library since I assume it will see a lot of usage.

Absolutely!

How do you return failure from main?

Just like in go: os.exit(1)

However, I'm not sure if an implicit $err is always the right solution. I'm worried about localization and internationalization of error messages in particular.

err value is set with return error(error_msg). Error message can be fetched via gettext for example.

Looking at the printing examples: Is it accurate that a variable identifier can be any character.

Can you explain what you mean?

What happens if you try to println() an array type? My intuition would suggest that a compilation error would have the least surprise, but you may want to do something else.

println supports everything that has a str() method. Arrays have that predefined. So println([1,2,3]) will print [1, 2, 3] :)

What even is an int? Is that a literal C int with all the risks of undefined behavior on signed overflow? Are unsigned types even available?

Very good question. This will be one of the first topics in the docs. V has byte, i16, int, i64, u64 etc.

int is not like in Go or C. It's always an i32. I just personally prefer int to i32. It's used in approximately 80% of cases in Go stdlib, so I made an exception for it. It goes against the philosophy of the language, but I really like having int instead of i32.

Are you making any guarantees about the C code output of a function that only does arithmetic on integer types and has no branching?

Could you please give an example?

Thanks

medvednikov commented 5 years ago

Or did you mean what happens if we call print([]User)? Compilation error :)

medvednikov commented 5 years ago

As for ', I want to have only one main way of denoting strings. V will automatically replace " with ' if there are no apostrophes in it.

I might remove " entirely and force developers to just escape apostrophes.

' strings can have $vars and newlines, unlike all other languages, yes.

burlesona commented 5 years ago

Just curious, why not go the other way with strings, and only use double quotes?

That seems more cross language consistent as it means you get variable interpolation etc., and in my experience apostrophes are much more common in strong literals than double quotes, so if you’re going to pick one the double quotes will require less escaping.

burlesona commented 5 years ago

Also, off topic, but since the above is my first post on your project I just wanted to say hello! V looks fantastic, take the good stuff of Go and make it even better (to me anyway).

Would love to help if there’s any way I can. Please let me know :)

slimsag commented 5 years ago

Will you keep raw string literals (backticks) from Go?

medvednikov commented 5 years ago

@burlesona JSON is very popular right now, and it has lots of ".

Also to me ''s look cleaner in the code and don't require shift.

But I had your exact thoughts, maybe I'll do that. Just to be consistent with other languages.

@slimsag ' behaves exactly like ` in Go.

burlesona commented 5 years ago

@medvednikov yeah it’s kind of tricky to balance, I think this is why most languages have a few string literal options :)

Maybe a block string literal syntax like Ruby’s heredoc (or many other examples) is a viable alternative for things like JSON input? But it does result in more than one way to make a string, which I agree isn’t perfect.

Or finally, less easy to type, but you could just go straight for backticks or some other universal string delimiter.

slimsag commented 5 years ago

@medvednikov Not true -- ' is a rune literal in Go and cannot contain multiple characters nor newlines and supports escape codes, in contrast ` is a raw string literal supporting multiple characters and newlines with no support for escape codes

oliwer commented 5 years ago

Hello @medvednikov and congratulations for V! It seems to solve many of Go's issues and could be a nice "better C". A few questions:

medvednikov commented 5 years ago

Hi @oliwer

since your functions are all lowercase, how do you differentiate between local and exported functions?

It's going to be either pub or some symbol like in Oberon.

  • can you tell us more about the what the runtime will do and how do you handle memory management compared to Go?

There's no runtime, memory management will be similar to Rust.

  • how do you declare a character/rune if ' is for strings? I understand that typing " is impractical with your keyboard, but you're a minority. Best thing you could do is switch ' and ", but I guess most people would hate it.

Backticks are used for characters. Which feels a bit weird.

Are there keyboard layouts that don't require shift to write "?

  • the error handling handling looks great! I also wanted to use or as that's what we often use in perl.

Thanks! I did some Perl in the past, that might have influenced the syntax :)

will V handle generics? :trollface:

It already does.

slimsag commented 5 years ago

Would be cool to see an example of generics somewhere!

boyter commented 5 years ago

+1 to seeing some example of generics.

rrjanbiah commented 5 years ago

OT: Will it be possible to convert Go code to V?

medvednikov commented 5 years ago

@slimsag @boyter I'll add an example with Generics soon.

@rrjanbiah yes, but coroutines and channels have to be implemented first.

International commented 5 years ago

Hi @medvednikov , does volt also use generics in it's codebase? Does it affect the compile times much?

medvednikov commented 5 years ago

@International no.

V compiler used to rely on generics to implement arrays and maps, but then I replaced them and made the code smarter (similar to Go's slices and maps).

There will be a way for users to create their own generic containers without generating extra code for each type and slowing down compilation time.

medvednikov commented 5 years ago

I've added an example with generics:

https://github.com/vlang-io/V/blob/master/examples/generic_repository.v

haltcase commented 5 years ago

I think it looks pretty good. I like a lot of the semantic choices you've made even if I don't particularly like some of Go's syntax that you're inheriting. I'm sure I'd get used to it though (except []User vs User[] that'll drive me insane :laughing:).

Immutability and first-class optionals (T?) with those nifty or blocks are great. I'm not sure I fully understand the way the or block works though. Do you always have to return from the outer function? How do you just do default values, or equivalents for some of Rust's Option methods?

It's going to be either pub or some symbol like in Oberon.

Either of these is good IMO, I don't like Go's capitalization rule for exports.

Backticks are used for characters. Which feels a bit weird.

It's probably best to use double quotes for strings and single quotes for characters but I understand the ease of typing isn't great for you. I use single quotes in JavaScript/TypeScript all the time but with everything else I code in using doubles, it can be a bit of a context switch.

Is there any short lambda syntax? (a, b) => a + b

How about pattern matching? It's one of my favorite features in Rust and ML languages, especially F#.


Is this a typo in the generic example? Should retrieve be find_by_id here:

https://github.com/vlang-io/V/blob/50d81e6edf1b7ed3c1ba0e24ce2c4b659b648b5a/examples/generic_repository.v#L34

medvednikov commented 5 years ago

Hey @citycide

Thanks for your feedback!

Is this a typo in the generic example?

Yes, I initially called it retrieve :) Fixed.

Do you always have to return from the outer function? How do you just do default values, or equivalents for some of Rust's Option methods?

Can you write a small example?

Is there any short lambda syntax? (a, b) => a + b

Not yet. Most likely there will be one. Need to think about the details.

How about pattern matching? It's one of my favorite features in Rust and ML languages, especially F#.

Same :)

Francesco149 commented 5 years ago

I'm very skeptical about the "400 KB compiler with zero dependencies" part. It just transpiles to C and then compiles with gcc/clang, doesn't it? that implies a dependency on gcc or clang. can the V compiler emit machine code by itself?

medvednikov commented 5 years ago

@Francesco149 this is a discussion about the syntax of the language.

V can compile to machine code directly, as well as to C.

dsnippet commented 5 years ago

Saw a couple of user examples that you published. V Looks interesting. Since I could not get enough information from the user examples, here are some basic questions that come to my mind.

  1. Does V (plan to) support OOP, inheritance, polymorphism etc?
  2. Parallelism?
  3. Systems Programming, as in support for pointers etc.
  4. Garbage collection?

I would be glad if you can point me to some documentation.

dsnippet commented 5 years ago

Also ABI compatibility with C/C++. Is it possible to link in C/C++ functions directly in V?

medvednikov commented 5 years ago

@dsnippet

1) No, it will be exactly like Go. Structs, embedding, interfaces. 2) Yes. Again, same as Go. 3) Yes. 4) No. 5) Right now you can call any C function: C.puts('hello world!')

awesomekyle commented 5 years ago

As someone who spends 98% of his time in C & C++ and has no experience with Go, any sort of "V for C Programmers" documentation would be very helpful. 😄 Looking forward to seeing V's release!

medvednikov commented 5 years ago

@awesomekyle V is language that can be learned in an hour.

A documentation/tutorial page will be out soon, and you'll see ;)

lasselindqvist commented 5 years ago

users.v says "V will automatically format and align your code." Does this mean the compiler changes the source files by formatting them?

xorhash commented 5 years ago

Looking at the printing examples: Is it accurate that a variable identifier can be any character.

Can you explain what you mean?

Sorry for the late response. I'd sent the message without finishing my thougts there. Is it accurate that a variable identifier can be any character that is printable and not $ or .? What is the source code file encoding (or is it always based on system locale)?


Are you making any guarantees about the C code output of a function that only does arithmetic on integer types and has no branching?

Could you please give an example?

Assume you have a section of code like this:

// a through d are mutable u32
a *= b;
c *= d;
b += c;
d += a;
// ...more operations...

Do you make any guarantees that the exact equivalent C code is output? That might be useful for cryptography, though it's already hard enough to write cryptographic algorithms in C in a way that your compiler doesn't sabotage you.

medvednikov commented 5 years ago

@lasselindqvist

users.v says "V will automatically format and align your code." Does this mean the compiler changes the source files by formatting them?

yes

@xorhash

Is it accurate that a variable identifier can be any character that is printable and not $ or .?

No, letters, numbers, and underscore only.

What is the source code file encoding (or is it always based on system locale)?

UTF-8

Do you make any guarantees that the exact equivalent C code is output?

You mean, will the resulting C code be the same? Right now, yes.

ducdetronquito commented 5 years ago

@lasselindqvist

users.v says "V will automatically format and align your code." Does this mean the compiler changes the source files by formatting them?

yes

Linting code tends in general to be done by an external tool; and IDE, a CLI tool, etc... It could be beneficial for the V compiler to avoid doing task that it do not needs to do :)

medvednikov commented 5 years ago

I know, that's different. But due to the design and philosophy of the language, it's a necessity.

rrjanbiah commented 5 years ago

OT: Perhaps all OT should be in https://groups.google.com/forum/m/#!forum/vlang

loic-sharma commented 5 years ago

V is looking great, I can't wait to play around with the language when it's released! :)

I don't have a background in Go, so this syntax feels strange to me:

fn (r Repo) find_by_id(id int) T? {
  ...
}

What're your thoughts on Uniform Function Call Syntax? Something like:

fn find_by_id(r Repo, id int) T? {
  ...
}

// Can be called two ways:
users_repo := new_repo<User>(db)
find_by_id(users_repo, 1) // No syntactic sugar
users_repo.find_by_id(1) // With Uniform Function Call syntactic sugar

This is great for method chaining too:

fn is_bob(user User) bool {
  return user.name == 'bob'
}

if users_repo.find_by_id(1).is_bob() {
  println('Hello Bob')
}
medvednikov commented 5 years ago

Hi @loic-sharma

One of the main philosophies of V is to make code readable, maintainable, and predictable.

One of the requirements for this is having only one way of doing things. Every single feature of the language has only one right way. The exception right now is string literals (see the ' vs " discussion).

If uniform function call syntax is implemented, every single function can be called in two ways. This is unacceptable, sorry.

V is a very strict language, and the one way only rule is going to make about half of programmers not happy by definition. C++, Nim, Rust, Scala etc are languages that support lots of paradigms and give developers lots of freedom. As the result, the complexity increases, code can get hard to understand, maintainability suffers.

Go has a similar philosophy. And I remember lots of people not happy about being forced to place { on the same line and using tabs instead of spaces. But in the end I think most will agree that it was the right decision that saved a lot of time (no more arguments on code styles and on which paradigm to use) and made code simpler.

What's wrong with fn (r Repo) find_by_id(id int)? fn (user User) is_bob() can also be chained.

loic-sharma commented 5 years ago

That's a fair response. There's nothing wrong with the existing syntax, it's just different for people that aren't used to Go. I'm sure we can get used to it 😄

medvednikov commented 5 years ago

Just published the first draft of the documentation. So far it covers the basics. https://vlang.io/docs

xorhash commented 5 years ago

The documentation tipped me off to it, but why does const API_URL = 'https://vlang.io/users.json' use = rather than :=?

It also seems weird to name a while loop for. Maybe just call it loop since the condition is optional?

medvednikov commented 5 years ago

@xorhash simplicity and consistency with other languages.

Having only one keyword instead of three (for, while, loop) helps keep the language smaller and simpler.

:= is used for variable declaration, const is for consts.

oliwer commented 5 years ago

By the way, you should mention in the documentation how to force the type of a variable. I suppose it would be like

myByte := byte(255) myReal := float64(0) // 0.0

Another possibility, incompatible with Go but "cleaner" in the sense that we would have only one affectation operator (=) and := would just be a short way of writing myVar : auto = 123 :

myByte : byte = 255 myReal : float64 = 0 something := 0xffff // let the compiler decide

I hope writing byte(256) would produce an error at compile-time and not at run-time.

-- Olivier Duclos

On Sun, Feb 24, 2019, at 14:07, Alexander Medvednikov wrote:

@xorhash https://github.com/xorhash simplicity and consistency with other languages.

Having only one keyword instead of three (for, while, `loop) helps keep the language smaller and simpler.

:= is used for variable declaration, const is for consts.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/vlang-io/V/issues/3#issuecomment-466772914, or mute the thread https://github.com/notifications/unsubscribe-auth/AAnXCgmq8lNzfuZwu8HS7lP_K7fEdlM7ks5vQo6qgaJpZM4a-WGd.

medvednikov commented 5 years ago

@oliwer updated, thanks.

ghost commented 5 years ago

The language looks very promising! In my opinion code is easier to read when the types are named int, intX, uint, uintX, float32, float64 and fn is named func (like in Go). And also the string syntax should be the same like in Go (in my opinion).

andrenth commented 5 years ago

Do you plan to introduce constructors in V? My biggest issue with go is the lack of constructors due to default empty values for everything. It’s effectively impossible to prevent instantiation with invalid state.

medvednikov commented 5 years ago

@tim-st V is being designed also for game development and science. Since conversions have to be implicit, there will be lots of float64( in the code. I think it's too verbose.

As for the function keyword, let's put it to vote: https://twitter.com/vlang_io/status/1099687714042114049 :)

medvednikov commented 5 years ago

@andrenth can you please post a simple example of instantiation with invalid state? Thanks.

medvednikov commented 5 years ago

I myself find u16 much more readable than uint16.

I think one of the unwritten rules of V is the fewer unnecessary keystrokes, the better. But within reason! (looking at you, Perl)

That's why there's no : between names and types, no -> before return types, no , in struct initializations, etc.

oliwer commented 5 years ago

@andrenth

My biggest issue with go is the lack of constructors

But you can already write constructors in Go (and I assume it's the same for V):

func NewThing(a, b string) *Thing {
  return &Thing{a: a, b: b, c: "default"}
}
andrenth commented 5 years ago

@medvednikov, building on the example @oliwer gave, one can always do t := Thing{} and bypass constructor validation.