6 ms·
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 ea
by fstarship 1y 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.
- chris_pie 1y agoI'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 1y agoI 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.
- chris_pie 1y agoAlso the Units of Measure are a great feature. I think they're a zero-cost abstraction that Rust users love to mention.
- ossopite 1y agoI'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?
- chris_pie 1y agoTo 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#.
- IshKebab 1y agoI 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.
- dustbunny 1y agoCheck out Wren. https://wren.io/ https://wren.io/ Written by Bob Nystrom, author of Crafting Interpretors.
- fstarship 1y agoThanks 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.
- pansa2 1y ago> 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.
- pansa2 1y agoWren is dynamically-typed, though
- sramsay 1y agoLast release was four years ago.
- dustbunny 1y agoLast commit was 3 weeks ago... Besides, it's "done" let it be done.
- oDot 1y agoYou're describing Gleam https://gleam.run https://gleam.run
- fstarship 1y agoThanks looks great so far. Also has pattern matching which I should also have mentioned in my top level post.
- macintux 1y agoAfter learning Erlang, it was painful to go back to any language which didn’t offer pattern matching. Such a great language feature.
- oDot 1y agoI 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 https://blog.nestful.app/p/why-i-rewrote-nestful-in-gleam [1]: https://porffor.dev/ https://porffor.dev/
- IshKebab 1y agoCan you easily embed it though? Looks like it depends on Erlang which means the answer is likely no.
- letmeinhere 1y agoFor one thing, inferred types may feel easy to use when implemented (well) but they are not easy to implement.
- rapind 1y agoI'd keep an eye on Roc https://www.roc-lang.org/ 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.html https://hexdocs.pm/elixir/main/gradual-set-theoretic-types.h... https://www.youtube.com/watch?v=giYbq4HmfGA&t=1s https://www.youtube.com/watch?v=giYbq4HmfGA&t=1s
- no_wizard 1y agoI want Clojure on Rust, or a similar LISP. Such a great programming paradigm that sadly has few breakout successes
- whytevuhuni 1y agoI'm having a hard time picturing that. What would it look like?
- no_wizard 1y agoLike Clojure having access to the Java ecosystem it would need access to the Rust ecosystem I imagine. I otherwise am unsure what you mean
- cultofmetatron 1y agoroc 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.
- Hasnep 1y agoIt'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.
- rapind 1y agoI 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.
- ossopite 1y agoI 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.
- nerdponx 1y agoNim 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.
- rattray 1y agoWhat happened?
- archargelod 1y agoIf 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 https://github.com/nim-works/nimskull commit 'drama' - https://news.ycombinator.com/item?id=32021299#32023998 https://news.ycombinator.com/item?id=32021299#32023998 nimony - https://github.com/nim-lang/nimony https://github.com/nim-lang/nimony
- threatofrain 1y agoImplicit 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.
- rTX5CMRXIfFG 1y agoI'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
- sanderjd 1y agoYeah 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.
- karmakaze 1y agoI 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.
- valenterry 1y agoRather 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.
- haxiomic 1y agoHaxe is the best fit for me, think of typescript with functional patterns and inferred typing. Written in ocaml and inspired by the language
- camdenreslink 1y agoYou could probably write F# in the style that you describe (it is a descendant of OCaml).
- pansa2 1y 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.
- pansa2 1y 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`.
- irh 1y agoYes 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.
- tuveson 1y 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.
- notnullorvoid 1y 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 1y agoRust 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.
- valenterry 1y agoYou 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
- beagle3 1y agoYou are describing Nim.
- zozbot234 1y agoRust 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 1y 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.
- simon_void 1y agocheck out Borgo https://github.com/borgo-lang/borgo https://github.com/borgo-lang/borgo It is Go with algebraic datatypes!
- mirekrusin 1y agoMoonBit lang is probably closer. Beautiful language.
- deleted 1y ago[deleted]
- teleforce 1y 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/ 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/glas-gemm-benchmark.html 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 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 https://youtu.be/CnKsOak0DHU
- deleted 1y ago[deleted]
- nine_k 1y agoThe 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 https://www.cs.yale.edu/homes/perlis-alan/quotes.html)
- sparkie 1y 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 https://github.com/stedolan/mlsub [2]:https://www.cs.tufts.edu/~nr/cs257/archive/stephen-dolan/thesis.pdf https://www.cs.tufts.edu/~nr/cs257/archive/stephen-dolan/the... [3]:https://github.com/hkust-taco/mlstruct https://github.com/hkust-taco/mlstruct [4]:https://dl.acm.org/doi/pdf/10.1145/3563304 https://dl.acm.org/doi/pdf/10.1145/3563304
- zozbot234 1y 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.
- sparkie 1y agoGradual 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 https://jsiek.github.io/home/WhatIsGradualTyping.html
- amedvednikov 1y 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 https://vlang.io GC, sum types, result/option types, interfaces, no OOP, fast compilation.
- egl2020 1y 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.