Hacker Newsnew | past | comments | ask | show | jobs | submit | fstarship's commentslogin

Also the wildcard system that means you get easy access to a tournament.

If you country hosts a grand slam Australia,Britain US, and France you can get some good prize money without winning a match.

Having the right flag beside your name removes lots of barriers


The Bevy game is an example on an organisation that has gotten 501c


It’s kind of like lots of imperial measurements where we use metric still have these in idioms.


"I would walk 500 kilometers" just doesn't sound as romantic.


Cities skylines 2 implementation is still pretty lackluster in related aspects.

Lots of buildings have forced carparks.

People are content to walk absurd distances.

I almost preordered when I saw mixed use zoning.


Forced car parks for buildings is at least accurate for a North American context.


> Cities skylines 2 is pretty lackluster

Fixed that for you. Huge fan of CS1, pre-ordered CS2, major regret. CS2 release felt like everything wrong with the game industry. Not sure I'll ever pre-order or support Colossal/Paradox again.


This video talks about it as well, it includes an interview with the author

https://m.youtube.com/watch?v=TgGoW5AIKEY


It seems every scripting language does duck/dynamic typing (as far as I can tell this applies to Koto).

I don’t understand why… inferred typing is nearly as easy to use while being more robust.

For me the biggest gap in programming languages is a rust like language with a garbage collector, instead of a borrow checker.

Rust has a lot of features that should be strongly considered for the next generation of programming languages such as

result/sum types

Inferred typing

Not object oriented or overly prescriptive with functional programming.

I think the closest language to filling that gap is occaml (I am not familiar with it).

I have coworker's that are more skilled in domain logic that can write basic self contained programs, but stuff like traits, OOP functional programming is a bridge too far.

I feel like a language that fills that gap could be useful, context is a manufacturing ERP system.


I think you really are describing ocaml, which is a great language, although its ecosystem isn't the best. It probably inspired most of the features you mentioned in rust. It also supports OOP (hence the O) but it's easy to avoid.

That said, I wouldn't compare it to scripting languages. The lack of implicit conversions / traits / ad-hoc polymorphism means it's not that convenient for scripting.


Fsharp, which originally was ocaml on dotnet, can also be run as scripts. It is a really practical way to start a project. I blogged about it here: https://asfaload.com/blog/fsharp-fsx-starting-point/


F# was never really "OCaml on .NET", though, not really. ML on .NET, sure, but it is (and always has been) missing OCaml's most interesting features, such as functors and OO with inferred row-types.


It probably was too much of a shortcut, thanks for the correction.


They have kinda positioned themselves that way and had (have?) syntactic compatibility with a subset of OCaml. And OCaml is probably the least obscure of the ML language family, so it's not exactly surprising.


Fsharp is such a nice languange. Such a shame that I never seem to get the light it deserves. Between the alternative light syntax, type providers and first class "scripting" mode supported it really was a great middle point between fully scripting language and fast prototyping and full blow projects


Ruby does very little implicit type conversion and is great for scripting. I think implicit type conversion is not required or even a good thing for scripting languages.


Implicit conversion is not obviously that convenient for scripting. The JS community has largely moved to anti-recommend implicit conversion, such as by basically striking `==` from their vocabulary.


What makes OCaml inconvenient for scripting is how difficult it is to run code that uses some external libraries. You basically need to create a whole project structure with several config files, which creates a lot of friction compared to `import numpy as np`.


Nim was great along these lines when I tried it. But that was before the v2.0 which apparently was accompanied by drama and a fork.


What happened?


If I remember correctly, main reason for forking was that Nim BDFL was writing lazy commit messages and old codebase was hard to navigate around. Some small part of community forked the language and trying to rewrite the compiler. According to readme they're not trying to replace Nim, but to create new language with Nim as base. Not sure how usable it's right now or will it ever be.

I also want to point out that Araq quickly took the criticism and his commits look a lot better now.

Also, core Nim team is currently working on their own rewrite of Nim compiler, called Nimony, that should evolve into Nim 3.

Refs:

fork - https://github.com/nim-works/nimskull

commit 'drama' - https://news.ycombinator.com/item?id=32021299#32023998

nimony - https://github.com/nim-lang/nimony


> It seems every scripting language does duck/dynamic typing (as far as I can tell this applies to Koto).

It looks like Koto supports type hints - not sure if these are checked at compile-time, run-time, or both.

> I don’t understand why… inferred typing is nearly as easy to use while being more robust.

Is it (nearly as easy to use)? Every static type system seems to have special cases and exceptions which are avoided by dynamic typing. I'd love to find one that's actually simple.

Also, it's definitely not nearly as easy to implement - which is important for a language being designed and built by a small team and targeting a lightweight runtime.


> Also, it's definitely not nearly as easy to implement

I think this is the real reason why there are so many dynamic language implementations. If you want to implement a dynamic language, you just slap a type tag on your runtime objects and boom, your "type system" is done.

Dynamic languages get a lot of expressiveness "for free", whereas having a really expressive static type system requires a lot of work. It's not that hard to get a type system on the level of C, but if the language is interpreted, it's still going to be pretty slow.

I do think there can be benefits to having typing in a scripting language (and not a bolted-on type system like typescript or mypy). It's much easier to work with an FFI if the type system of the scripting language maps closely to the implementation language. It also does make it much easier to optimize the language down the line, if that becomes a priority. Making a fully dynamic language efficient is very, very difficult.


> not sure if these are checked at compile-time, run-time, or both

It looks like Koto only checks types at run-time. That means its type annotations are essentially shorthand for something like Python's `if not isinstance(...): raise TypeError`.


Yes that's right, they're checked at runtime (with the option to disable the checks if the performance cost is a concern) and failed checks simply throw exceptions.

The hints aren't used for other purposes at compile time yet, but they could enable some warnings.


> I don’t understand why…

Because dynamic typing has its own advantages, which are worthy of experimentation even if you perceive absence of static typing as a weakness.

Gradual typing can offer us the benefits of both worlds.

> inferred typing is nearly as easy to use while being more robust.

Implementing type inference can be fairly trivial if your types are all disjoint. Hindley-Milner type inference is well studied and there's plenty of literature.

But as soon as you introduce subtyping, the traditional methods are not sufficient. It's only in the past decade that good solutions have been discovered, notably Dolan & Mycroft's MLsub[1], based on Dolan's Algebriac Subtyping thesis[2], and Parreaux & Chau's MLstruct[3], which uses a boolean algebra approach[4]. Type inference with subtyping is not a solved problem - these developments are big steps forward, but there are still open problems under research.

Subtyping doesn't imply object-oriented. Structural typing (ie "static duck typing") is a form of subtyping.

[1]:https://github.com/stedolan/mlsub

[2]:https://www.cs.tufts.edu/~nr/cs257/archive/stephen-dolan/the...

[3]:https://github.com/hkust-taco/mlstruct

[4]:https://dl.acm.org/doi/pdf/10.1145/3563304


> Gradual typing can offer us the benefits of both worlds.

Gradual typing has much the same overhead as other kinds of dynamic typing. It's broadly appropriate as part of the interface between separately-developed software components, and not very much otherwise.


Gradual typing is static typing augmented with a known static type `dynamic`, and some rules by which conversions to/from `dynamic` are statically checked, called consistency.

A program in a gradually typed language which does not use `dynamic` is fully statically checked and has no overheads. The overheads only appear when `dynamic` is used.

This is why it offers the best of both worlds. We get static typing everywhere where we're not using dynamic, and when we do use dynamic, we can basically use it however we want and have the benefits of dynamic typing, because from the static perspective, dynamic ~ dynamic, regardless of what the runtime type is.

The important innovation is that consistency (~) is not transitive - so it doesn't allow us to implicitly convert one type to another - only conversions to/from dynamic are implicit, and other conversions must be done explicitly.

Obviously, this provides an "escape hatch" from static typing where we do use it - we can get around some static type check by casting to/from dynamic explicitly, but this works out well in practice.

C# is an example of a gradually typed language since v4 which introduced `dynamic`.

Haskell is close , in that it has the type `Data.Dynamic`, but it doesn't support implicit conversions to/from it, which would be possible if it had a consistency rule. We have to do the conversions explicitly.

https://jsiek.github.io/home/WhatIsGradualTyping.html


I'd keep an eye on Roc https://www.roc-lang.org/

Also, Elixir is working on gradual types, which is something I would keep an eye on. https://hexdocs.pm/elixir/main/gradual-set-theoretic-types.h...

https://www.youtube.com/watch?v=giYbq4HmfGA&t=1s


roc as a language looks really interesting but its by elm devs and I don't have much confidence in their ability to handle the transition to being a widely used language with all the cultural shifts that requires.


I hear ya, but Elm allowed me to eject out of the javascript churn for the past 7 years while still building some slick UIs that basically never fall over. I literally don’t know or care what the current hotness is in javascript, and that’s how I like it.

If roc ends up being even close to that productive for me, I really don’t care how widespread it is. I like these thoughtful unrushed languages that I can support for years without stress.


> but Elm allowed me to eject out of the javascript churn for the past 7 years while still building some slick UIs that basically never fall over.

Thats the real tragedy. Elm was a good language but the culture around it means it could never achieve critical adoption. It is great technology for building frontends but how easily will I be able to maintain that app as the web changes over the years?


I can only speak from experience, but it's been absolutely solid, incredibly easy to maintain (because there's been so little change), and I don't feel like I missed out on any groundbreaking front end tech at all. I literally have some elm code that's been in production doing it's thing for 7+ years without any maintenance, but more importantly it's not scary to open it up and make changes 7 years later either.

I doubt it's a silver bullet for everyone, but it's been phenomenal for me as a solo dev w/ my own product. I feel so much better about my elm code than I do about my React code. I have to do all the other things, like marketing, sales, training, support, back end, etc. It's nice to launch a UI and know it'll last (and also that it's easy to refactor and augment too!). Elm has turned my into a statically typed functional fanboy. It's been a gateway drug to Haskell, OCaml, and F#.

I see the same promise with Roc, although I bet Richard will update it more frequently than Evan w/ elm after 1.0.


which culture and why it cased problems ? honest question, I barely heard of elm


It's created by Richard Feldman who was big in the Elm community, but I think most contributors to the Roc compiler have only used Elm a bit or have never used it.


FYI roc is in the early stages of a complete rewrite from Rust to Zig and... that may take a while. I'm messing with Nim in the meantime for some commandline tooling


I want Clojure on Rust, or a similar LISP.

Such a great programming paradigm that sadly has few breakout successes


I'm having a hard time picturing that. What would it look like?


Like Clojure having access to the Java ecosystem it would need access to the Rust ecosystem I imagine.

I otherwise am unsure what you mean


Rust will probably gain support for "pluggable" and optional garbage collectors as part of its upcoming local allocators API. This will ultimately give devs the best of both choices - use tracing GC where it's actually needed (because you're working with totally general graph-like data and that's the only feasible memory management strategy) and manual memory management (supplemented by RAII and reference counting) elsewhere - for other parts of the program that don't have to manage general "spaghetti" graphs. Unfortunately the way GC's trace objects and collect garbage varies wildly among implementations, so there's no easy way to standardize a "generic" interface to pluggable garbage collection, that all custom crates might be expected to tap into by default. But other uses should be quite feasible.


> Rust will probably gain support for "pluggable" and optional garbage collectors as part of its upcoming local allocators API.

Source? AFAIK there's no confirmed upcoming allocators APIs, and even if there was they would just allow reusing the builtin `Box`/`Vec`/etc etc with custom allocators. This is not much different than what you could do with a custom type, so I find it hard to believe it would allow garbage collectors that are not possible right now.


I'm not sure what you're getting at here but none of the features you mentioned are groundbreaking anymore? At least in Swift:

result/sum types = enums whose cases have associated values

inferred typing = Swift "type inference"

Not object oriented or overly prescriptive with functional programming. = Uh, yes

Those features map to Kotlin too


I don't think you're disagreeing with parent. I also think these features are not groundbreaking and should be considered table stakes for any new/sane language.


I am aware of 3 “rust inspired scripting” languages that have dynamic types.

Rhai Rune Dyon

Mun is not dynamic, however it does not have string support afaik.

Kotlin and Swift may be better candidates than these scripting languages for my imagined usecase.

Come to think of it, maybe I don’t have a point other then there is so many scripting language’s inspired by rust that is dropping a major convenience feature, that I am surprised is negotiable (inferred typing ).


Rust itself has dynamic types via the Any trait and &dyn Any variables. They are not the default of course, but they're available should you really want them. IIRC C# works similarly, only its feature is called Dynamic instead, or something like that.


They're rather different: In Rust types only exist at compile time; dyn Any is a normal trait object, so you can only call the trait's methods. With C#'s dynamic, you can call arbitrary methods and access any fields with type checking of those accesses being delayed until runtime, which works because types exist at runtime too.

Rust's dyn Any corresponds better to C#'s Object; dynamic exists to interface with dynamic languages and is rarely used.


Yeah I think Kotlin is quite close to the OP's description. But it is perhaps more focused on object orientation than they would like, and also only runs on the JVM.

But if I were to create a self-contained (that is, non-JVM) "Rust-like but with GC", I think it would look a lot like Kotlin.


I haven't tried it but Kotlin/Native targets platforms like iOS, macOS, Linux, Windows, etc. There's also Kotlin/JS for JavaScript, and a WASM target with limitations.


It's been a few years since I tried Kotlin/Native but even then it was pretty good.


Neat. I didn't know that.


Rather Scala but leaving out a few parts. Kotlin is very very OOP focussed and comes with a lot of baggage from Java.

Rust-like but with GC is already Scala. The reason is that Scala (unlike Kotlin) focusses on immutability, which makes it more similar to Rust. It's actually even easier to use (no borrow checker) but at the cost of performance.

After Rust, I would see F# as the next closest language, quite far before Kotlin.


> Rust-like but with GC is already Scala.

Maybe like a third of Scala. But yeah, Scala has a lot of good parts, it's also just a huge surface area. I agree that you could pluck a subset out of Scala and make it this "Rust-like but with GC" language.

But it's nigh-impossible to actually make that "only use this subset" idea work in practice, because it just ends up being a bikeshed.

But you're right that the same can be said of the OO focus of Kotlin.


I think it absolutely works in practice. You have to pick the right libraries though. I would start with https://github.com/com-lihaoyi which basically follows that style.

> But you're right that the same can be said of the OO focus of Kotlin.

The difference is that Scala focuses on immutability, which makes the experience much closer to Rust than to Java. Whereas Kotlin does it exactly like Java does. Were Kotlin to focus on immutability like Scala does, than I would recommend Kotlin over Scala for what OP asked for.


A language is a shared way to communicate. If you start picking and choosing the parts of a language you like, you can no longer communicate effectively with the rest of its speakers, er, coders.

That's why C++ is so badly designed, you can do anything in it, so people do and no two C++ codebases are the same. Your codebase at work is written one way, the libraries it uses in another, your personal projects use something else entirely. It's a huge mess where nothing is compatible with each other and the mental load of switching between projects is untenable.


That's kind of true, but it's not black and white.

For example, look at Golang. The syntax is very plain and it's by design so that everything looks the same.

Then take a look at Lisp. On the surface the syntax looks all the same but in reality, everyone can write their their own macros and people usually do. Then, you can barely understand what's going on if you are new to the codebase - but on the other hand, the flexibility is enormous.

Scala is somewhere in between. When you hire someone for Golang, you don't really need to make anything clear in terms of code style (I believe). In Scala (or Lisp) you should definitely clarify the style that you use. It's actually normal (I've hired pretty big number of Scala developers over my career and I have also rejected job offers due to the style the company uses which doesn't match what I like).

C++ probably is alike, but I don't really any C++ experience.


Scala is a lot more like lisp in this way (or actually, the C++ comparison is the much better one) than it is like go.

There are lots of ways to write Scala, to its detriment.

This isn't meant as a knock on Scala! It's a great language and in particular I think it's been influential on other newer languages. It's just that it does have this "multiple dialects" issue.


Check out Wren.

https://wren.io/

Written by Bob Nystrom, author of Crafting Interpretors.


Thanks for your suggestion.

At first glance it appears to be object oriented, which is against preference but not a deal breaker.

However error case looks to be try catch which is a deal breaker.


> However error case looks to be try catch which is a deal breaker

Wren uses coroutines ("fibers") for error handling, which is unusual. But yes, ultimately it does seem to be equivalent to try-catch.


Last release was four years ago.


Last commit was 3 weeks ago...

Besides, it's "done" let it be done.


Wren is dynamically-typed, though


You're describing Gleam

https://gleam.run


Can you easily embed it though? Looks like it depends on Erlang which means the answer is likely no.


It also compiles to Javascript, which runs in a lot of places (to say the least). For WebAssembly, see my other comment about Porffor


Javascript isn't the nicest thing to embed either tbh. It looks like a nice language but it's clearly not in the same space as Lua or Rhai.


Thanks looks great so far.

Also has pattern matching which I should also have mentioned in my top level post.


I use it in production[0] and it's a delight so far. When Porffor[1] is ready you could compile to WASM through JS for self-contained binaries!

[0]: https://blog.nestful.app/p/why-i-rewrote-nestful-in-gleam

[1]: https://porffor.dev/


After learning Erlang, it was painful to go back to any language which didn’t offer pattern matching. Such a great language feature.


>For me the biggest gap in programming languages is a rust like language with a garbage collector, instead of a borrow checker.

I cannot agree more that's the much needed sweet spot/Goldilock/etc. Personally I have been advocating this approach for some times. Apparently the language is already widely available and currently has stable and wide compiler support including the venerable GNU compiler suite (GDC). It also one of the fastest, if not the fastest programming in existence for both compilation and execution [1].

It has been beating Fortran in its number crunching territory, no small feat given the Fortran pedigree with many languages still depending on Fortran based infrastructure for their number crunching capabilities including Matlab, Julia, Rust, Go, C, C++, etc [2].

It also has a nice bulti-in REPL system due to its very fast compilation and execution [3].

For an excellent overview of D programming language please check this presentation at ACCU conference [4].

[1] D website:

https://dlang.org/

[2] Numeric age for D: Mir GLAS is faster than OpenBLAS and Eigen:

http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...

[3] Why I use the D programming language for scripting (2021):

https://news.ycombinator.com/item?id=36928485

[4] How DLang Improves my Modern C++ and Vice Versa - Mike Shah - ACCU 2024:

https://youtu.be/CnKsOak0DHU


The point of many scripting languages is quick tinkering, mucking with stuff in a REPL, on top of a complex contraption of already-live objects. This works well with duck typing. It does not work with nice static type inference, because once you change something high upstream, it potentially invalidates everything downstream, your entire current session you've spent an hour building.

"Everything should be built top-down, except for the first time" (See #15 in https://www.cs.yale.edu/homes/perlis-alan/quotes.html)


For one thing, inferred types may feel easy to use when implemented (well) but they are not easy to implement.


I totally agree. I think it's simply because most of these projects are pretty much one-man efforts and implementing static typing is a lot more effort than dynamic typing.


I'd say F# is closer to filling that gap than OCaml. It's a bit less insistent on being functional and has a more familiar syntax. I find it more practical in general.


I somehow discovered F# by accident and it’s really an hidden gem.

Its ahead of its time in basically every aspect, it’s 100% compatible transparently with the whole C# ecosystem, it’s mature yet still evolving.

The type system is something I never saw before : creating types is so ergonomic and fast that you can create custom type for basically any value of your program without boilerplate if you want.

It’s really a refreshing language that anyone should try.

What I really love with it is that it’s hard to write (when you are learning it) but incredibly clear to read.


Also the Units of Measure are a great feature. I think they're a zero-cost abstraction that Rust users love to mention.


I'm curious what you have in mind when it comes to ways in which OCaml is insistent on being functional while F# isn't. After all, OCaml has mutable data structures, mutable record fields, for loops and so on. Is it just that more libraries assume immutability and use functional abstractions?


To be fair, my knowledge of F# is a bit basic, but I meant stuff like classes (including abstract ones), interfaces, and the ingrained interop with C#.


Haxe is the best fit for me, think of typescript with functional patterns and inferred typing. Written in ocaml and inspired by the language


check out Borgo https://github.com/borgo-lang/borgo It is Go with algebraic datatypes!


You are looking for Scala or F#, depending on your choice of ecosystem.

Both come with very powerful features, but you don't need to use them and you can use libraries accordingly. Especially Scala can be made to feel very similar to python


> For me the biggest gap in programming languages is a rust like language with a garbage collector, instead of a borrow checker.

I agree, though I often think Rust is probably good enough. You can use RC or grab a GC crate. It's not as ergonomic as just assuming all values are GCed, but I think it gives the flexibility and fast iteration of working in a GCed language.


Rust is not as good as D in this domain in which D is designed for this, since it's GC by default, please see my other comments.


> I don't understand why.

Favors minimal text entry. You keep the type information in your head and enter fewer tokens. Historically you also reduced the work and improved responsiveness for the interpreter, which might have been running on an 8- or 16-bit computer at 5 MHz.


You are describing Nim.


You could probably write F# in the style that you describe (it is a descendant of OCaml).


> For me the biggest gap in programming languages is a rust like language with a garbage collector, instead of a borrow checker.

https://vlang.io

GC, sum types, result/option types, interfaces, no OOP, fast compilation.


MoonBit lang is probably closer. Beautiful language.


For your specific counting problem you can use relative line numbering which shows line numbers relative to your cursor.

However the larger attempt and redo problem you highlighed is mitigated in a modal editor that does selection first (not vim) instead of action so you get a preview of what you will delete before hitting it, you can also expand it.

I did give up vim for the same reasons, but I am happy with Helix.

I won’t deny that I still make lots of errors, I still use vscode for other features like folder search and replace, easier diff comparisons


> a modal editor that does selection first (not vim) instead of action so you get a preview of what you will delete before hitting it, you can also expand it.

This is pretty much what Visual mode does. V4jd is

* V: enter visual line mode. * 4j: select the next four lines (in addition to this one) * d: delete.

The selection is highlighted before the delete command, you can change the selection range, etc.

I use visual mode to replace stuff all the time: V10j:s/foo/bar/g It even shows the changes interactively.


I did actually do that when I tried Vim but it felt clunky.

The find and replace is more at folder level with vscode previews only terminal equivalent I know is serpl


For that you can use a quick fix list.


You can do selection first in Vim by using visual mode. For this particular example (5dd) you would want to use visual line mode by pressing shift-v. Then you can select the lines you wish to cut, and press d to delete them, or apply any other action to that block of text.

I frequently use c (change) on my visual selections, type in new code at the point where it was removed, then use p to paste the old code somewhere else.


What does GoT stand for?


Game of Thrones. I was just making a (bad?) joke about the popular conception of things that happened between Caesar and Napoleon.


I would have guessed war of the roses, which got us based on.


Gulf of Tonkin incident and the iron throne of Saigon.


Or it should be called Caelus to be consistent with Roman names


We could always go back to calling it George, like Herschel initially did.


Consistency is the hobgoblin of minor planets


Depends where you live, cities are still growing, like in Japan Tokyo still grows while the rest of the country shrinks.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: