Do all the things like ++ or -- rants, post your own rants, comment on others' rants and build your customized dev avatarSign Up
From the creators of devRant, Pipeless lets you power real-time personalized recommendations and activity feeds using a simple APILearn More
12bitfloat7151290dI feel like it's one of those "C-killers" that only look a bit different and have some nicer syntactic sugar without actually being that innovative when it comes to real issues (memory safety, zero cost abstractions, robustness) and ultimately fail to gain any traction because of it
To be fair I haven't used it extensively but it's clearly inspired by Rust and having used that quite extensively I don't really see how you can implement Rust without any of the "annoying" stuff. Can't have your cake and eat it too
12bitfloat7151290dSome of the claims seem a bit dubious too...
No global variables? I get that mutable global state is a problem, but we need _some_ form of global state even if you force me to have it be thread safe.
Pure functions by default? I guess could be cool for (some niche) optimizations, but no other imperative language I can think of could ever effectively implement pure functions without them just being an annoying road block and then not actually providing the promised optimization opportunities because of some very nuanced compromises
Also garbage collection... so I dunno. Seems like a cool language overall but not necessarily cooler than some others
“Safety: no null, no globals, no undefined behavior, immutability by default”
They make some big claims about this, no idea how it works in practice though.
But what got my attention:
“Performance: as fast as C (V's main backend compiles to human readable C)”
Are we really transpiling...?
I looked at some of the examples they have on github, and I must say I kinda have to praise them for one aspect.
Their goal is "simple, readable, and maintainable code." and honestly the examples look really nice and clean
BlackCenti24290dI've tried out V language before, it have some frictions that I didn't like about it. For a language that transpile to C language, it have vastly different syntax compared to C language counterpart.
The biggest plus is probably the generic implementation, but it's interesting when it produced significant amount of bloat of unused code in final binary compared to C language.
So overall, I have some ires about V Language and didn't agree with the language design choices, so I dropped it.
bittersweet46846290dI applaud everyone who writes their own language.
V seems to be quite a project, with a rich feature set, the docs don't look too bad either.
There are some really juicy bits in there, especially regarding memory management, using compile-time embedding of free calls which avoids both GC'ing and a Rust-style borrow system.
Does that mean I would consider using it? Nah.
Well, maybe for some hackathon.
For a language to become mature you need a giant community, amazing clear and complete documentation, and a rich ecosystem.
Rust is just about arriving at the point where I don't have to defend the choice to coworkers anymore.
V is at version 0.2, and I bet there are still plenty of ways to make it leak memory or segfault.
LotsOfCaffeine3771289dI read through V's docs.md (https://github.com/vlang/v/...)
one nit pick would be the naming of primitive types
there's i8, i16, i64, u16, u32, u64.
u8 and i32 have special names (byte and int) for whatever reason
One thing that does put me off heavily though is the interfaces:
>"A type implements an interface by implementing its methods and fields. There is no explicit declaration of intent, no "implements" keyword."
this means any struct implicitly implements your interface if it just happens to have the same method defined.. idk about that
other than that I feel like the V devs are aiming for a simple language, and I think I can appreciate that, even if I find the syntax a bit odd, personally
> this means any struct implicitly implements your interface if it just happens to have the same method defined..
I don't see this as a problem. Haskell turns the whole concept inside out btw:
Every function has a (generic) type signature. Any type which fits the type signature, can use the function.
Interfaces are contracts about the... well, interface. That means, to satisfy a "jsonserializable" contract, you must have a toJson method, which (probably) returns a json string.
How that happens, doesn't matter, interfaces do not guard the implementation logic.
Also, just because the jsonserializable interface says "I'm just gonna auto-apply myself to this type, because it looks good to me", doesn't mean other interfaces can't do the same.
There might ALSO be a jsonable, stringable and an validAPIresponse interface which all say "if it has a "toJson" method, I personally approve that type to be used in specific places".
@bittersweet yeah I just don't like this kind of implicit-ness (is that a word)
I don't want to accidentally implement an interface, worst case some user sees it, thinks it's intentional and assumes my type behaves as the interface documents it to.
V also implements iterable types for their for loops by having a generic function called next() that returns some optional value.
@LotsOfCaffeine I don't think an interface should be documented, the implementation should be.
There are advantages to implicit interfaces — extensibility for example.
In Haskell, this takes rather extreme forms.
Module A of a Minecraft type game might define some data structure "Chunk"
Module B might need that data structure to be mappable (it implements the Functor interface by defining a method fmap with type (a -> b) -> f a -> f b), as it wants to be able to transform a Chunk of blocks into a Chunk of blocks plus lighting data.
Even if module A didn't make Chunk mappable, module B can implement it as mappable.
Module C can then say "my render function needs mappable chunks with block & light data"
With many OOP languages, from Java to PHP, you're kind of stuck with the definitions provided by upstream maintainers.
If a package provides a User object, you can't easily say "I want to denote that User perfectly implements my aftermarket interface".
12bitfloat7151288d@bittersweet Implicit interfaces are a pretty bad idea if you care about robustness. A simple function signature just doesn't hold enough information to determine compatibility. I mean that's what docs are for! If it was enough info we wouldn't need docs because the code would document itself. But since it doesn't the only entity able to determine this sort of stuff is a human and so they should have to explicitely declare "yes, this function actually implements this contract"
As for external extensibility: That works just as well with explicit interfaces! You do that all the time in Rust and it works great. Take a look at https://docs.rs/itertools/0.10.1/...
@LotsOfCaffeine I'm using it daily next to PHP, mostly together with https://rocket.rs.
We have a giant PHP/Laravel monolith, so I'm using it to split off badly performing parts into (micro)services with better performance & safety.
Especially for finance/invoice handling it has paid off, we handle large volumes of orders with a lot of credit/tax/scheduling/transaction complexity -- A solid type system helps a lot.
Also for performance-critical parts with hit/miss handling layers on top of Redis caches it's nice to work with a compiled, well-performing, non-GCed language to make API endpoints.
The String stuff... doesn't bother me. It's pretty logical to have a (dynamic heap) "String" thingie which is a growable Vec<u8>, and a more primitive fixed size "str" slice, which might be static if you're using it as a compiled label.
Why doesn't it bother me? IntelliJ yelled "THIS SHOULD BE "hello world".to_string() YOU FUCKING RETARD" at me for a few weeks, you get used to it.
12bitfloat7151288d@LotsOfCaffeine Yeah Rust can get pretty complex but I think it does a good job still staying sane unlike C++ which often becomes batshit crazy for seemingly no reason
If you aren't too much into Rust right now that sentiment is understandable though. It's one of those languages where from the outside nothing seems to make any sense but once you've grokked it you suddenly feel enligthened
@bittersweet yeah the conversion between the two types always confused me
@12bitfloat someday I'll get into it a bit more I guess. Doubt it'll be at work since it's mostly C++ (embedded software).
I'm getting along with C++ sort of well now, though it is still very much annoying.
One thing I don't get about rust is modules though
I did a lot of C# and frankly it's just so much easier there. Put your file in the project directory, define a namespace and that's it.
@LotsOfCaffeine Yeah modules are a bit confusing if you're used to other forms of namespacing.
First, because all files are implicitly modules. A math.rs file, is directly the "math" module.
Second, because there are two common patterns: You can have math.rs, or math/mod.rs.
In the latter case, the mod.rs file is generally used to just aggregate sublibraries, set visibilities and re-exporting/aliasing.
@LotsOfCaffeine This explains the Rust module situation quite well:
Article also mentions that it's "weird" coming from other languages.
Personally, I don't think it's necessarily wrong or limiting in any way though, just a bit awkward depending on what you're used to.