Val, a high-level systems programming language
val-lang.dev
val-lang.dev
Statically compiled. Statically typed. Interops with C++. Memory safe. Typesafe. Data-race-free.
The elevator pitch I give when describing it goes like this: Imagine you were starting a new C++ project and didn't really care about performance (spoiler: perf comes back in the end). So, you decide to not bother using pointers or references anywhere. You just pass by value, return by value everywhere, all day long. If you ignored the obvious perf problems of passing around maps of vectors of objects by value, wouldn't it be nice? you don't have to worry about side effects or data races or anything. And yet, the data is not immutable. You can go ahead and mutate it all you want worry-free because the data is all completely local to your function.
Well, turns out the Val folks have figured out that by eliminating pointers and references from the language, the can get the compiler to automatically pass-by-const-reference and return-value-optimization under the hood such that it preserves both the performance and the semantics that you want at the same time.
Val: A Safe Language to Interoperate with C++ - Dimitri Racordon - CppCon 2022 https://www.youtube.com/watch?v=ws-Z8xKbP4w
Adobe Research labs is seriously sponsoring its development.
So it is for C++ what rust is for C?
In Rust there are some things you can't (safely) do because the checker can't see why they're ok. Val guesses that, with appropriate language features in place, you can extend that to everything and still have a useful language but now you don't need to teach this complicated and difficult feature.
Because Val is young it's not yet obvious whether this is basically always better, or whether it's too limited.
On top of that being a generally shite language doomed Eiffel.
[1] IIRC again, you could cancel features in subtypes, so "all birds can fly" but "penguins are birds but can't fly". That would break the Liskov Substitution Principle, which Bertrand Meyer thought he could deal with but apparently couldn't.
Eiffel Software is still in business, whereas many others hardly reach any audience.
In regards to Eiffel, always felt that hindrance to wider adoption was more about the licensing. Still, they are in business and in use.
This is sound wisdom. It's not always obvious at the beginning what the limitations are going to be, and what the opportunities are going to be. If it's a promising direction, pursue it, even though it won't always work out.
It turns out that although we've often thought of this as a variety of different hard problems, including "data races" and "use after free", they're actually all one big problem, that of mutating something while somebody else used it. Solving this effectively solves all of those hard problems, at least in a subset of your language where you are able to address it.
In a language like C or C++ it's easy to make one or more references to a Thing, and then give away the references, or the Thing, or both, and then the programmer loses track (or maybe never knew they were related) and these nasty surprises are their reward.
In Rust, their borrowing / lending metaphor prevents the surprise. If you lend a mutable reference to the Thing, the borrower can't destroy it, that's not what "lending" means, and you can't even use it until they've stopped borrowing it. If you lend immutable references, nobody can destroy it, or mutate it at all, until all those references are given back. But this does make the language more complicated because of the new metaphor.
In Val, you can't have any references, so unrelated_function couldn't destroy Thing, you've got Thing, so unrelated_function doesn't have Thing and can't destroy it. No surprises.
No, "solving" this by preventing it in the first place just makes programming way too hard.
In practice, using something while other people are using it is perfectly fine in most cases. E.g. most Python programs do that, and most don't have bugs most of the time.
The "use-after-free" problem can far more easily be solved by removing `free` (e.g. by using Garbage Collection).
Most concurrency bugs remain even if you solve all data races (e.g. as Python does, with GIL) simply because the semantics are wrong (e.g. having to update 2 counters which cannot happen simultaneously), or iterating through a list while modifying it (no data races here if done from a single thread!).
I'd argue Rust is more aimed at the C space than the C++ space because of its accent on systems programming.
also some languages have packages that deal with c++ interop to varying extents - see this discussion: https://www.reddit.com/r/ProgrammingLanguages/comments/huhy8...
NimForUE takes advantage of this: https://youtu.be/Cdr4-cOsAWA
It is implemented as a library, without needing compiler support [*].
You can write C++ in TemplateHaskell (Haskell's strongly typed AST-generating macro system), which allows you to use Haskell variables in scope inside your C++ functions.
The "inline-c" library allows this for C and C++.
Example of its use in the Haskell OpenCV bindings: https://hackage.haskell.org/package/opencv-0.0.2.1/docs/src/...
The way it works: It invokes the C++ compiler for you to generate a wrapper function that closes over the Haskell variables used in your code snippet, and on the Haskell side generates a corresponding type-safe function call for you.
This approach allows you to use all C++ features that a C++ compiler supports. But it also carries the drawback of ... invoking a C++ compiler, which gives you the slow build speed of C++.
[*] Some compiler support was added to be able to specify compiler flags that are specific to the C++ compiler but not the C compiler.
That said, if you're all in on it I imagine that the front-end could pretty aggressively target that, much like how rust uses no alias.
References need to be specified as mutable if mutation is needed (i.e. `&mut T` instead of just `&T`). Using immutable references is also encouraged from the borrow checking rules; having a second reference (either mutable or immutable) alive at the same time as a mutable one is a compiler error, but using multiple immutable references at the same time is fine. (Pointers are the same way, but not really used much outside of bridging with unsafe Rust, since they can be null and therefore can't be dereferenced outside of `unsafe` blocks).
This is certainly the case in c++: distinct objects have distinct addresses, so to remove a copy the compiler has to prove that the aliasing is not observable which is hard.
But does rust have the same guarantee?
I honestly don't understand what you've said here at all. I'm not familiar with what "observable" means in this context, and googling "observable aliases programming languages" didn't help clarify it (two results were articles about C/C++ aliasing, one of which used the term "observable" once but didn't seem to define it at all, and the other which was the Wikipedia article on "Aliasing (computing)" that didn't contain the term at all).
Even if I knew what "observable" meant, I think you might be missing a negation (or maybe including one you didn't mean to) somewhere; if addresses are "kinda considered observable", it's not obvious why it would be an issue to omit copies and "be observable". Maybe understanding what's meant by "observable" would shed some light on what you mean here, but naively, I don't understand how code that expects things to "kind of" hold a property would break if that property were somehow more strongly held.
EDIT: https://learn.microsoft.com/en-us/dynamicsax-2012/developer/...
A+ becomes AA C++ = CCC Clik++ never mind this was a bad call. JJJ RRR Visual JJJ XXX (nice) xBaseee ZZZ
[0] https://en.wikipedia.org/wiki/List_of_programming_languages
It would have: • garbage collection (Shake It Off) • error correction (Bad Blood) • closures (Closure) • optionals (Would’ve, Could’ve, Should’ve) • automatic reference counting (Right Where You Left Me) • REPL (I Knew You Were Trouble) • variable mutability (Everything Has Changed and Evermore) • guard condition (Eyes Open) • strict typing (You Belong With Me)
After compiling run the binary by issuing the command: Run {filename}
To debug: Tell Me Why {filename}
That is all I know about Taylor Swift. But it seems like you are onto something here. :D
Yes, you can replace a block of unsafe calls with a bunch of individually unsafe-annotated lines. But a good model of unsafe to follow is that whatever unsafety you expose within a block should be brought back within safety requirements when you exit the block. Put differently, an unsafe block should act as unit-safe and not leak unsafety.
If all you get is statement-level unsafety, you have no way to indicate at what point you’ve re-upheld safety guarantees.
Does it? With what qualifications? Requires C++ that uses clang modules or something?
EDIT: I assume you meant to copy "ìnterops with C++". The answer is that it basically doesn't right now, but they intend for it to in the future somehow.
And if that's a goal, fine, but if there isn't interop yet, we should be hesitant to describe Val as having C++ interop. Especially since C++ interop probably requires some compromises, such as requiring modular C++ in some form.
I cannot efficiently mutate or even store references in structs anymore. That seems to be a show-stopper if you want to have any non-trivial or non-standard data structures in the program. Granted, they are hard to get right, so maybe it's a feature.
As for the safety mechanisms discouraging non-standard data structures, the language designers probably would consider that a feature, rather than a bug.
I am curious whether the use of a broken unsafe construct can break the safety guarantees of safe constructs, or if the unsafety is contained no matter what.
Newbies to Rust have a lot of trouble learning how to get the borrow-checker to accept their code, but what these restrictions are doing is syntactically ensuring there are no deadlocks or data races. It is presumably a similar story with Val.
If Val actually handles this differently, I'd love to know.
The Pony language has something analogous to Rust's ownership system (there it's called reference capabilities [0]), but in addition to that Pony prevents deadlocks too [1]. It does so by not providing locks, but only providing actors with message passing (channels). Now, Pony is a much higher level language and unsuitable for some of the low level stuff that Rust does.
If you restrict your Rust program to not use locks, but just send messages through channels between threads [2], you won't have deadlocks either. But that's quite a handicap for a low level systems language, so Rust in general can't commit to that.
[0] https://tutorial.ponylang.io/reference-capabilities/referenc...
[1] https://www.ponylang.io/discover/#what-makes-pony-different
[2] If you would rather prefer to write async code, there are async channels too, but to be deadlock-free you need to always guarantee that your futures are polled https://rust-lang.github.io/wg-async/vision/submitted_storie... which is maybe a strange requirement that's alien to most languages
> If you restrict your Rust program […] you won't have deadlocks either.
So Rust is directly superior, because it gives you a choice? I get it, there is something nice about having an enforced paradigm, so you're not forced to work with foreign 'bad' code, but I don't understand your argument:
> But that's quite a handicap for a low level systems language, so Rust in general can't commit to that.
Rust is fast, so it can't afford being slow. Pony solved this problem by being a slow, high-level language, so now it can block fast solutions and get away with it, because it's slow anyway, and therefore it's presented as a superior alternative to Rust - which can do the exact same thing, and have at worst the same speed as Pony, but we expect more from Rust (because it's better) therefore it's worse? Just doesn't make sense to me, sorry :D
Again, I see the advantage in the aspect of a language being simpler, and enforcing a paradigm on the ecosystem so developers have less head scratching to do when cooperating.
What's nice about Rust is that it enforces a safe paradigm at first, but over time one learns Rc, RefCell, unsafe "rustonomicon" to be able to optimize. In *the* Rust book, channels are taught first, immediately at the beginning of the chapter about threads.
This is actually how I've been writing PHP programs for years, passing arrays around like I just don't care.[3]
I think the PHP interpreter is smart enough to actually only copy-on-write, but I admit I've never profiled these programs. But anecdotally, I've done some pretty complex stuff[1] this way and it never caused noticeable performance problems.
[1] Complex as in 'wow I sure am making the computer process a lot of data, parse some DSL character-by-character, dynamically generate SQL and massage the results into some arbitrary structure for EACH PAGE LOAD, geez'. Not as in 'print hello world, but using Laravel', which somehow manages to be about 30x as computationally expensive[2].
[2] quip about how 'web artisans' spend the time between page loads brewing coffee using their CPU as a heating source while thinking deep thoughts. But I digress.
[3] Back in the PHP 4 days, objects, too, acted as if stored in variables rather than just pointed-to by them. Not that anyone expected language design excellence from Rasmus et al, but strikes me as a missed opportunity when they changed object variables to having reference semantics to have 'value, variable reference, or pointer-to-value' be a property of variables orthogonal to the type of value they store/reference. e.g.
$a = $b; // Copy $b's value into $a
$a = &$b; // $a and $b are now the same variable
$a = *$b; // $a points to the same object as $b, but unlike $a = &$b, the variables themselves are not linkedDoubt. I simply don't believe any other language out there is capable of interoperating with C++. Even C++ compilers have broken binary compatibility, different versions of the same compiler even.
battery included stdlib that also has network and gui is super attractive too
Not using one of them is making oneselfs live difficult on purpose.
C already felt primitive in the mid-1990's, and by C++98 most of those features were available.
So they can use C++ for those fixes, with its JavaScript/TypeScript kind of symbiotic relationship for better or worse, or stick to C and keep waiting for such language, that will most likely require parsing include files with some kind of tooling.
It's more for service-oriented applications currently... you pass stuff in, get stuff out.
https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webas...
To me it initially looks like WASI does not let you use WASM as a bare metal language (I don't know enough about WASM to judge whether that's even really sensible). Instead, you have a layer on the bare metal (or even several layers above) implemented otherwise, and then you can use WASM still further above, to interface to that layer.
But again, maybe I misunderstood.
- https://github.com/bytecodealliance/wasm-micro-runtime
- https://github.com/bytecodealliance/wasmtime
- https://github.com/wasmerio/wasmer
- https://github.com/tetratelabs/wazero
- https://github.com/extism/extism (disclaimer, my company's project - makes wasm easily embeddable into 16+ programming languages!)
There is also Carbon and CppFront but those are more of C++ evolution than new-born things.
The bad ergonomics of C were never enough to get another language into the Linux kernel, it took a language that solves the number one class of security bugs. It's unclear that any successor to Rust will be able to show as clear a need.
K&R C was, what, 1972...and it's 2023 now. So that's 51 years with no definitive end of 'making do' in sight.
AFAIK no silver bullet has been discovered yet that would be an improvement over Rust that doesn't have some other trade-off. Val's mutable value semantics is more local and limited. It "solves" the problem of ugly lifetime annotations by not supporting complex zero-cost lifetimes at all. That doesn't mean Val can't be successful — it can be easier to use by supporting simpler constructs and focusing less on zero-cost abstractions, like Swift, but its ideas aren't stop-the-presses for Rust.
We're already overdue for having a more modern, practical replacement for C. Waiting for a hypothetical better-than-Rust language will only mean staying with C for even longer.
Uhh no. No that is not “the question”.
My question is “what language will I use to write video games”. C++ sucks and Rust isn’t a great fit.
It’s a very interesting language that does a lot of things “very right”. But it’s also a long ways from being broadly available.
I don't think that the "window of opportunity" for another language in the kernel has closed. If anything, Rust has shown what would be the hurdles to overcome, so it may inform the next attempt if it happens.
And of course Linux is not the only kernel out there, and new kernels can also arise.
Oh neat, a new systems language, probably nothing but let's take a peek. Docs look legit. Hmm some thoughtful ideas in here around ownership. Syntax makes sense. But is it different enough to justify its own existence? Who makes it?
Oooh, Dave Abrahams is working on it. We crossed paths at Apple and I remember his Crusty talk about Swift [1]. It was great, loved the strong opinions, but Apple sadly removed it years later because it had some outdated advice. Wait, he's at Adobe now? So is this an Adobe language?
Conclusion: keep an eye on it, will watch the linked talks, wait and see.
[1] edit: I found the Crusty talk! "I don't do Object Oriented!" https://www.youtube.com/watch?v=p3zo4ptMBiQ
He ending up in the Val project is not surprising!
- https://github.com/val-lang/val/issues/758
- https://github.com/val-lang/val/issues/711
That smells bad implementation. You should self-host ASAP guys, you'll find more basic bugs like that. Yet 500+ stars !
Self hosting is also not the be-all and end-all. It is a symbolic milestone, more than anything. Achieving it is something to celebrate, but not something to hold against the language until much later on their development cycle, if at all.
Carbon has yet to deliver on anything yet, even as Sean Baxter has been making lots of progress on the Circle compiler (including implementing lots of the good bits from Carbon).
Hard to be a successor when you can't really be considered a language yet.
The name didn't matter at all, it could have been named Fooscript and still be popular.
Val, a new programing language inspired by Swift and Rust - https://news.ycombinator.com/item?id=31788527 - June 2022 (19 comments)
The following phrases got my eye: "It is reasonable to ask, then, how we can use mutable value types to represent self-referential data structures, such as doubly linked lists and directed graphs. In fact, any arbitrary graph can be represented as an adjacency list. For example, a vertex set might be represented as an array, each element of which contains an array of outgoing edge destination indices.". I don't see how one can reasonably implement doubly-linked list without re-inventing memory heap and some kind of garbage collection in the implementation.
UPD: found some discussion at https://github.com/orgs/val-lang/discussions/736 , seems that there will be some escape hatches akin to Rust's `unsafe`. That resolves all issues, and "whether the safe subset of Val is enough for reasonable application" question is open to long years of debate.
It's much less silly than one could think, because these indices are locked to your particular data structure (doubly-linked list, graph, etc) and cannot be manipulated to access anything else in the program, at least not easily. This applies bot to the compiler checking that, and to the attempts to crack the program.
Are they, though? Consider I have a linked list (or a map/dictionary, or any data structure that allows removal of arbitrary elements). I add elements with indices 1, 2, 3, 4, 5. I remove elements with indices 2 and 4. I'd like to make memory consumed by these elements available again. At the same time I don't want to change indexing scheme of the whole data structure. So I have to keep "holes" with indices 2 and 4 at the very least. After few million operations that may become very inefficient.
In a typical language, that would be resolved by having a global allocator that allows indices 2 and 4 to be reused in neighboring data structures. If I don't implement a global allocator that shares indices between objects (as that kills the whole point), I consume more memory than needed and rely on my own clunky implementation of garbage collection/defragmentation, don't I?
But what irks me is: why not just program in plain C with passing structs by value ?? All aliasing will be gone and probably compilers already know how to deal with that. "Becouse somehing_hard_to use is included" is just dumbing thing down and not gaining much. Lack out of bound indexes checking ? That's like one function. Call it everywhere :) Programmers need to learn dealing with reality (what features CPU's gives) instead of being castrated. Becouse moving problem somewhere else do not annihilate problems. Maybe we need high level CPU's and some hw level guarantees some engineers can bake in :) But that can end like hardware on call register saving :)
...no unnecessary allocation occurs. The result of *longer_of* is a projection of the longer argument, so the mutation of z by *emphasize* occurs directly on the value of y. The value is neither copied, nor moved, and yet it is not being passed by reference to emphasize
I'm not sure how to read this. A string arg is supplied to a function and a character is (or characters are) appended to it. How can this happen without a new copy of y, since that string must have had an initial lengh (and therefore, a specific place and size on the stack)? Do they create strings with extra padding at the end, just in case someone might append to them? (If so, how much padding and why isn't that generally less efficient overall?)Edit: I didn't realize that asterisk bolding didn't work in quotes. Decided to leave it in anyway.
To better understand, notice that longer_of is not a function; it’s a subscript. A subscript does not return a value, it projects one, granting the caller temporary read and/or write access to it.
I'm not really sure how this doesn't fall under a move? Regarding the string, they could also place it on the heap to allow for the variable sizing, which is what Rust does.That said, I was wondering about a similar thing: what if I modify a 1GB string? Is it copy-on-write?
I feel like it can be optimized away 99% of the time only to leave you with 1% of cases that result in very-hard-to-find performance degradations.
Right. But the context of the example made me imagine it probably was -- since I would likely reject out-of-hand any new language that always allocated variables on the heap.
Generally on HN people (myself included) seem to use the '> ' tradition for quoting, which the parser doesn't treat specially but works out fine.
Maybe these cases can be simplified, but I’m very skeptical. It’s a fundamentally difficult problem domain considering that these cases are also very difficult to reason about in C/C++. Questions like: will this request last longer than the current thread?
A humble suggestion to anyone coming up with a new language.
Please make it as familiar as possible.
For example, do you really need to come up with some new syntax for defining a function, or specifying types and returns?
If you want people to use your new language, reduce the cognitive load - do things the same as other languages and be different only where you must.
Every time you come up with some completely alien programming construct, you have set a barrier to learning. Coming up with a new language should, for the most part, be an exercise in copying the best of how other extremely popular languages do things, and on top of that build in the necessary differences that make your language special.
Also, less is more. For example, one of the reasons Rust is so complex and intimidating is it has six sublanguages https://gist.github.com/brendanzab/d41c3ae485d66c07178749eae...
the expression language
unsafe runtime language
safe runtime language
compile time language
the type language
the trait language
the macro language
the attribute language
Whereas Zig goes the other direction and attempts to make everything programmable in the one core language, even ditching macros entirely. https://ziglang.org/learn/overview/. In Zig you can write compile time code in the same language and same code base.I put forward these suggestions not as a language edxpert - I am far from it - instead I put them forward as a frustrated learner wanting to do new things and looking at new languages and thinking "shit, I already work with three of four languages plus any number of subtechnologies on a given system, I just don't have time/headspace to learn a programming language with six sub languages".
Additionally Dave Abrahms would like to have another go at designing Swift.
My point is not so much about syntax, it is about unnecessarily doing things in a conceptually different way.
If different behavior at a given point is core to what makes your language special then sure thing, make it behave different, but implementing some different behavior without a significant payoff only makes your new language harder to grasp.
Presumably you are making a language because you have some core concepts or beliefs you want to bring to life - all I'm saying is - make that happen, and make the rest as familiar as possible for most programmers.
If Rust goes the explicit modifier route, e.g. something can be & and also mut, and you need to know what these are, Val goes the implied behavior route where a ‘set’ parameter can be set, while a ‘let’ parameter can’t.
If they didn’t come up with new semantics, they’d just be making a Rust clone. I for one am very looking forward to how Val develops. Currently it seems like it can offer similar guarantees to Rust while using a simpler mental model to deal with.
I’m curious to see how they are going to tackle concurrency. Their roadmap outlines that as one of the trickier parts given the semantics that they’re going for.
But seriously, if you aren't doing something really different, why bother. If you find Popular Language X (PLX) too limiting, there's probably a dozen or two "it's just like PLX, but with a sprinkling of things from Y, which is pretty much like PLX, but sweeter sugar, and that makes it perfect". As others have pointed out, syntax is trivia[1].
[1] Unless, of course, you think a BEGIN..END language is nifty, and then you're a heretic and someone is coming with torches and pitchforks. :-)
I think most programmers have been trained to think that C like syntax and semantics is fundamental to programming languages, as if languages are just inherently C like, and that C is just what programming is, but this is not true.
Programming language theory is an entire field of study on it's own, and there are a lot more possibilities than just rehashing C for the nth time.
This evasive phrasing, which continuoes after this excerpt too, has me highly skeptical of their good intentions… Any good reason they are not more explicit?
What the seem to be saying here is that the "subscripting" operation returns a view into its argument, not entirely unlike the concept of a lens. The only thing that view can be used for is directly accessing the the part of the value that is in focus—the view is not itself a first class value, which means that so-called "reference semantics" don't come into the picture.
I don't think they're being evasive or promoting their idea in bad faith. They are just operating in a characteristically arcane way for C++ language design people.
The following blog post helped me start to grasp what this aspect of C++ talk is actually about: https://akrzemi1.wordpress.com/2012/02/03/value-semantics/
To me, this seems like a proliferation of distinctions and enthusiastic theorizing. Finding solutions which actually simplify the task of programming and/or clarify matters seems a long way from this attitude.
Val just doubles down on the ideas in Swift and goes so far as to remove references altogether. This is a really interesting space.
I was hoping there was because i liked the idea when it was announced a year ago, but the page doesn’t seem to show anything new.
For Val, I was a little hesitant when I saw the docs say "Two or more types can form a union type, also known as a sum type." since a union type and a sum type are similar but distinct concepts.
For a language, it is very important to understand the differences between these because I think they will greatly impact the design of the language.
It's understandable why a company like Apple would seek Swift to be familiar to developers, but I don't know why new efforts that will be building a community from scratch would do this.
We need more imagination and more bold deviations from the norm, if any of these languages will make sense to pick up for a dev out there.
But I miss an ecosystem of people doing something about it. This variety is required for healthy progress in a field. So people can inspire one another, and lead to significantly new efforts. One instance is nothing, despite of course everyone believes they're making the language that'll take over the world.
I often open a new language's site, anticipating innovation and how what I do compares with them. And it's always disappointing to see "it's like X but slightly better" because "X but slightly better" has no chance to overtake an incumbent, and also it shows attitude where we think all there's to discover has been discovered, and it's just tweaks and patches now on, with a new brand label on top.
Nothing can be farther from the truth.
> We need more imagination and more bold deviations from the norm
This is what I reacted on, a bit too compactly - apologies. Let me unzip.
My problem is that this statement 1) feels so far removed from reality, 2) I'm so much interested in this space that this hurts.
Why would you recommend others to throw out the good ideas of decades of research just to be hip? Evolution doesn't work that way. Humans didn't evolve by throwing away state-of-the-art apes. Evolution happens by changing one or few bits at a time and iterating while selecting for the good. This means there will be many programming languages that look just like those before them - at least to the untrained eyes.
Mutable value semantics is one of the most fascinating ideas in programming. It's like the good parts of functional programming without the bad parts. I'm pretty certain it will revolutionize programming. To dismiss it as being close to existing languages blows my mind.
I get that it's hard for any language to take hold without being 10x better. At the same time, it feels naive to build a 10x better language without keeping the good parts of existing languages. Not removing good ideas is as important as adding good ideas.
Also, humans are 'stateful', switching costs are real. 10x better not only includes the upsides but also the downsides. Hence, it feels like a sane strategy to not only maximize the upsides of new ideas, but at the same time minimize the downsides of not only removed good ideas but also changes in general, to minimize switching costs.
I'm not a systems programmer, but I thought there was a consensus these days that this was a Bad Idea™? Are the benefits of marginally better performance on certain platforms really worth having your program break due to an overflow when you run it on a different platform?
For me, this would be an essential part of being a "safe" language. And I bet this is the kind of safety we need more than just memory safety.
Is my reading of overloads correct? Identically-named methods are supported, but only for different argument labels and/or calling conventions?
Rust convinced me that dispatching based on argument types is a poor idea, because Vec::new(10) could only be understood by reading the documentation at least once - whereas Vec::with_capacity(10) is abundantly clear. Val seems to gain these benefits (assuming that it doesn't dispatch based on type) without the drawbacks.
Having some code suddenly gain a gigantic copy in an inner loop because of a far away change seems like a risk in val.
"Subscripts are often used to refer to members of a mathematical sequence or set or elements of a vector. For example, in the sequence O = (45, −2, 800), O₃ refers to the third member of sequence O, which is 800." (Wikipedia)
As fanf2 said, projection in software typically refers to selecting one element of a tuple.
"[Projection is] An operation typified by the jth projection map, written projⱼ, that takes an element x = (x₁, ..., x ⱼ , ..., xₙ) of the Cartesian product X₁ × ⋯ × Xⱼ × ⋯ × Xₙ to the value projⱼ(x) = xⱼ" https://en.wikipedia.org/wiki/Projection_(mathematics)
I saw the example they gave, which is cool, but they were with string literals. So, per my question above, how would the same program work if the strings came from user input?
I understand this is the second approach.
Isn't this the same effect as we get when using Copy-on-Write, e.g. with the implicitly shared container classes Qt offers?
... to which architecture(s)?
Then for other languages its media blackout, hate, and an avalanche of trolling. I suppose the hidden machinery and utility accounts don't come out, unless "they" perceive an actual threat to its position.
Don't get me wrong, love new languages and seeing more competition. People should follow their dreams. Just weirds me out, as to how reactions and perception goes.
The groups of people who criticize real tangible languages and people who have the skills to critique the design of abstract language design don't necessarily overlap.
Val has promised a lot and hasn't delivered anything, so I think it's fine to be interested/ excited but have a heavy dose of scepticism as well.
Now, I just want to make it clear that my exact wording here was "people were rightfully critical of V" and not "people are rightfully critical of V" (emphasis added). My intent is not to malign the current state of V, because 1) I do not keep up with the language and 2) it isn't relevant to the point being made.
The parent comment was drawing a comparison between "other languages" (which, by now, it's apparent that they're speaking primarily about V) and Val when it comes to HN's reaction. If we're going to compare, it only makes sense to compare them at similar stages of development / release. So, in this case we're talking about early release V and what was promised versus delivered. It does not matter what is being done in service of users now because the criticism I'm referring to isn't from now, but when the initial HN impressions of V were formed.
Can you please list here actual examples of under delivering and misrepresenting?
I'm sure your programming language is just fine. What's far from fine are these flamewars. Everybody, on all sides of this, needs to stop doing it on HN. Other forums are fine with flamewars; please conduct them there instead. It's not what this site is for, and destroys what it is for.
The prog lang world is a massive circle jerk, with plenty of toxicity, extreme fanboy-ism and haters.
This is not a random language.
? I dunno where you’re getting this from.
Pony? Zig? Crystal? Carp? Taichi? Dex? Vale?
The reception has been generally positive imo? Vale got some complaints for being very rough, but the reception was pretty much ok?
I mean, those are just things I’ve seen flow past on HN, so maybe others drop off and never see the light of day, but that’s true of most links on HN in general.
To rise up and then get heaps of negativity seems unusual for a programming language?
You sound quite “conspiracy theory” with this, and I think you’re sitting in a weird echo chamber.
If anything, I’d say the big difference is that this is broadly speaking a technical audience; a language that is not pitched at a technical audience (or exaggerates for marketing purposes like getting funding) will just get downvoted as spam.
Val has an open source compiler you can look at right now (not vapour), clearly points out it’s not ready for use, but has big ideas.
Doesn’t seem like you need a “deep state” to be enthusiastic about competent people building a new language, and having a chance to push it in a direction you personally want as it evolves.
It's not based on conspiracy or throwing out a quick unresearched opinion to just smite someone. It's based on search, and reading posts made on HN (over the years).
> (exaggerates for marketing purposes like getting funding) will just get downvoted....
> (not vapour), clearly points out it’s not ready for use, but has big ideas...
The difference is, being consistent with handing out such punishments (downvoting) and giving negative labels (vapor). Treat all the languages the same or equally apply those rules, otherwise the hypocrisy shows itself. Don't be so angry or surprised that someone may comment on it or point it out.
And when using terms like "vapor", let it be one's original thought, and not what is supplied by others painting a certain narrative.
???
Isn’t that literally what I’m doing with my examples of like 6 different programming languages?
> Don't be so angry or surprised
I apologise if I somehow came across as angry; I’m simply stating a fact.
There is no conspiracy.
I'm just pointing out that there are several idioms, nomenclatures, slang, blah blah that when stated "high level" is condescending and making it that "i dont need to explain myself to you!!"
But yet, you DO have to explain yourself
- It uses "0o" instead of "0" prefix for octal numbers.
- Underscores to separate groups of digits in numeric literals.
Not good:
- It uses Unicode.
- It does not have a "goto" command.
- There are no macros.
- Perhaps, the name is too similarly than the other programming language, maybe?
This isn't everything that can be commented about it; I have not examined it completely yet.
programming languages do not themselves need to be programmable
To maintain the code, you have to understand the input language to the code generator and its metaprogramming constructs. You're no better off in that regard.
The grandparent comment is saying that if you don't give people metaprogramming built-in, they will resort to outboard metaprogramming.
I.e. you can't stop people from metaprogramming.
macros are programs written in a separate, unique, often turing-complete meta-language, which is implemented entirely in the compile phase of the language which supports them
they're in no way equivalent
The Racket people took this concept very far. The kernel of the language is very small and well defined. All Racket programs (or more precisely, expressions) are eventually reduced to a handful of syntactic core forms (see [1]). For example, thanks to forms such as (#%variable-reference id) you can specify rules for variable access, for example, w.r.t. life-time. With tools such as the Macro Stepper you can fully step through the transformations of any expression in your program, from the highest to the lowest level.
This has numerous benefits. Extensions or modifications of the language can be rolled out (and used!) as libraries. This makes collaboration and testing far easier. Also, if a language feature turns out to be a bad idea, you deprecate the library. You do not have to change the compiler. This allows you to shrink your language and explore different directions without the burden of an ever growing language spec and implementation.
Is it a perfect solution? No. Changing a widely used language always has big impact, but the impact can be compartmentalized and users of the language are given a graceful migration path by updating their libraries, at their choice and pace.
Is Racket perfect? No, not by a long shot. But, frankly, language authors should at least take a look at the possibilities and consider the technological options for controlling the evolution of a language.
https://docs.racket-lang.org/reference/syntax-model.html#%28...
(this is PG's take, but IIRC the thread as a whole had some interesting ideas. Unfortunately Guy Steele's replies seem to have been under a different Subject: and haven't been threaded by the archive)
Edit: HN to the rescue: https://news.ycombinator.com/item?id=9695323
One thing that C does not have something like METAFONT's "vardef"; if you have "scoped macros" that can be declared as global or local variables and as members of structures, it would cause less interference than the current system and can even sometimes provide other benefits too.
Others include e.g. possibility for macros to define other macros (probably several other programming languages have such a thing), for appending to existing definitions (like {append} in Free Hero Mesh), for altering existing macros with a value calculated immediately instead of each time the macro is called (like {edit} in Free Hero Mesh), etc.
What is not good about being able to use unicode? For me not being able to process unicode is an instant fail.
However, processing Unicode is often unnecessary anyways. Sometimes you only need to deal with ASCII (and can pass through non-ASCII unaffected). Sometimes the Unicode handling can lead to bugs (and sometimes can be security problems; and this is not usually due to Unicode being implemented incorrectly). Unicode can also make the code less efficient especially when Unicode is unnecessary but sometimes even if you do deal with Unicode (due to internal conversions and counting and other stuff it is doing when it is not helpful or might even be against what you are trying to do). Inherent Unicode handling can also sometimes make it difficult to handle byte strings especially if they do not have many of the same operations available to them.
It also tends to lead to bad design (API design and programming language core design). Sometimes it is used even though byte strings would be more appropriate, or sometimes you might want a separate "file path" string type (I think Common Lisp does this). Treating source files as Unicode text can also be probematic.
Unicode is not a very good character set anyways; it is bad in many ways. I could say what ways it can be bad for many different languages and for other purposes such as security and efficiency and accessibility, too. (Some people say it is better than dealing with other character encodings for multilingual text. I have worked with it and found the opposite to be true.)