top | item 43515249

(no title)

fstarship | 11 months ago

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.

discuss

order

ossopite|11 months ago

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.

jeltz|11 months ago

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.

threatofrain|11 months ago

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.

xigoi|11 months ago

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`.

nerdponx|11 months ago

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.

pansa2|11 months ago

> 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.

tuveson|11 months ago

> 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.

pansa2|11 months ago

> 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`.

sparkie|11 months ago

> 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

zozbot234|11 months ago

> 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.

rapind|11 months ago

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

cultofmetatron|11 months ago

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.

no_wizard|11 months ago

I want Clojure on Rust, or a similar LISP.

Such a great programming paradigm that sadly has few breakout successes

zozbot234|11 months ago

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.

SkiFire13|11 months ago

> 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.

rTX5CMRXIfFG|11 months ago

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

madeofpalk|11 months ago

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.

fstarship|11 months ago

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 ).

sanderjd|11 months ago

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.

dustbunny|11 months ago

Check out Wren.

https://wren.io/

Written by Bob Nystrom, author of Crafting Interpretors.

fstarship|11 months ago

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.

sramsay|11 months ago

Last release was four years ago.

pansa2|11 months ago

Wren is dynamically-typed, though

oDot|11 months ago

You're describing Gleam

https://gleam.run

IshKebab|11 months ago

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

fstarship|11 months ago

Thanks looks great so far.

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

teleforce|11 months ago

>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

nine_k|11 months ago

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)

letmeinhere|11 months ago

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

IshKebab|11 months ago

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.

chris_pie|11 months ago

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.

pjerem|11 months ago

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.

ossopite|11 months ago

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?

haxiomic|11 months ago

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

valenterry|11 months ago

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

notnullorvoid|11 months ago

> 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.

teleforce|11 months ago

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.

egl2020|11 months ago

> 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.

beagle3|11 months ago

You are describing Nim.

camdenreslink|11 months ago

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

amedvednikov|11 months ago

> 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.

mirekrusin|11 months ago

MoonBit lang is probably closer. Beautiful language.