7 ms·
I love the idea of a "thought experiment language" - actually creating a working language is a big overhead, and its really fun to think about what an ideal lan
by benrutter 3y ago
I love the idea of a "thought experiment language" - actually creating a working language is a big overhead, and its really fun to think about what an ideal language might look like.
The crazy thing with reading this and the comments, is that it seems like we all have been daydreaming about completely different versions of a "high level rust" and what that would look like. For me I'd just want a dynamic run time + simpler types (like "number" or a single string type), but it looks like other people have a completely different list.
Some of the additions here, like a gradual type system, I would really not want in a language. I love gradual type system for stuff like Python, Typescript and Elixir, but those are cases where there's already so much untyped code written. I would way prefer the guarantees of a fully static typed codebase from day one when that's an option.
- brainzap 3y agoI agree, fantasy and play is needed. Since we humans have a brain area for play and imagination, why not explore.
- thesz 3y ago> actually creating a working language is a big overhead Languages, with first class values, pattern matching, rich types, type inference and even fancy RTS, often can be embedded in Haskell. For one example, it is very much possible to embed into Haskell a Rust-like language, even with borrow checking (which is type-checking time environment handling, much like linear logic). See [1], [2] and [3]. [1] http://blog.sigfpe.com/2009/02/beyond-monads.html [2] https://www.cs.tufts.edu/comp/150FP/archive/oleg-kiselyov/overlooked-objects.pdf [3] http://functorial.com/Embedding-a-Full-Linear-Lambda-Calculus-in-Haskell/linearlam.pdf Work in [3] can be expressed using results from [1] and [2], I cited [3] as an example of what proper type system can do. These results were available even before the work on Rust began. But, instead of embedding Rust-DSL into Haskell, authors of Rust preferred to implement Rust in OCaml. They do the same again.
- pas 3y ago> instead of embedding Rust-DSL into Haskell, authors of Rust preferred to implement Rust in OCaml why? and how much does it matter, if the goal is to have a compiler/interpreter? (as I assume is the case with Dada, and was with Rust)
- argiopetech 3y agoR&D. Bootstrapping.
- ericyd 3y agoAre you suggesting that creating a new programming language from scratch is a trivial exercise? If yes, wow. If no, I think the intention of your comment could be more clear, particularly regarding the quote you took from the original comment.
- couchand 3y agoI suspect the GP was merely suggesting a less-costly alternative. Perhaps building a complete standalone compiler or interpreter is hard, but we're all designing APIs in our programming languange of choice day in and day out. Both strategies are very hard, but one of then is "build a prototype in a weekend" hard and one of them is "build a prototype is a month" hard.
- jacobr1 3y agoIt is interesting to consider how much the lower abstraction influences the higher abstraction. If you are building on a existing language/runtime/framework then you can inherit more functionality and move faster, but also you implicitly will inherent many of the design decisions and tradeoffs.
- couchand 3y agoVery good point. See, for instance Kiselyov's embedding of his tagless final form: https://www.okmij.org/ftp/tagless-final/course/lecture.pdf https://www.okmij.org/ftp/tagless-final/course/lecture.pdf
- convolvatron 3y agototally. for me the interplay between the host language and the target language is hardest thing for me to manage when bringing up a new environment. it really doesn't seem like it should be a big deal, but it comes down to the sad reality that we operate by rote alot of the time, and completely switching semantic modes when going between one world and the other is confusing and imposes a real cost. I'm still not that good at it, but my best strategy to date is to try to work in a restricted environment of both the host and the target that are nearly the same.
- pas 3y agoRuntime would be nice, but ... that's basically what Tokio and the other async frameworks are. What's needed is better/more runtime(s), better support for eliding stuff based on the runtime, etc. It seems very hard to pick a good 'number' (JS's is actually a double-precision 64-bit IEEE 754 float, which almost never feels right).
- benrutter 3y agoYes, that's true - "number" is probably more broad than I'd really want. That said, python's "int", "float" and "decimal" options (although decimal isn't really first class in the same way the otherse are) feels like a nice balance. But again, its interesting the way even that is probably a bias towards the type of problems I work with vs other people who want more specification.
- jacobr1 3y agoThe key though is probably to have a strong Number interface, where the overhead of it being an object is complied away, so you can easily switch out different implementations, optimize to a more concrete time at AOT/JIT time and have clear semantics for conversion when different parts of the system want different concrete numeric types. You can then have any sort of default you want, such as an arbitrary precision library, or decimal or whatever, but easily change the declaration and get all the benefits, without needing to modify downstream code that respects the interface and doesn't rely on a more specific type (which would be enforced by the type system and thus not silent if incompatible).
- mike_hearn 3y agoThat sort of stuff is easy to do with Truffle (which, ironically, lets you define a language using what they call the "truffle dsl"). The SimpleLanguage tutorial language has a bigint style number scheme with efficient optimization: https://github.com/graalvm/simplelanguage/blob/master/language/src/main/java/com/oracle/truffle/sl/nodes/expression/SLAddNode.java#L64 https://github.com/graalvm/simplelanguage/blob/master/langua...
- 3y ago
- sanderjd 3y agoIn college, my programming languages class used a language called "Mystery" (I believe created by my professor), which was configurable. Assignments would be like "write some test programs to figure out whether the language is configured to use pass-by-value or pass-by-reference". And there were a bunch of other knobs that could be turned, and in each case, the idea was that we could figure out the knob's setting by writing programs and seeing what they did. I loved this, both as a teaching aid, and as an eye-opener that programming languages are just an accumulation of choices with different trade-offs that can all go different ways and result in something that works, perhaps a bit better or perhaps worse, or perhaps just a bit more toward or away from one's own personal taste. This is sort of the lisp idea of "create the language that is natural to write the application in, then write the application". Or Ruby's take on that idea, with more syntax than lisp but flexible and "human" enough to be DSL-ish. But somewhat to my sadness, as I've progressed in my career, I've realized that the flip side of this is that, if you're building something big it will require lots of people and all those people will have different experiences and personal preferences, so just picking one standard thing and one standard set of defaults and sticking with that is the way to go. It reduces cognitive overhead and debate and widens the pool of people who can contribute to your effort. But for personal projects, I still love this idea of thought experimentation around the different ways languages and programming environments could work!
- couchand 3y agoDon't be so quick to discount DSLs. Sure, you don't want a half-baked DSL when some simple imperative code would do. But if you watch your API evolve into an algebra and then don't formalize it with a DSL you might be leaving powerful tools for understanding on the table. A poor-fitting language is terrible for abstract thinking, on the other hand an internally-consistent and domain appropriate language can unlock new ways of looking at problems. I'd highly recommend Martin Fowler's work on DSLs to see how you can apply these techiques to large projects.
- jacobr1 3y agoA related notion is that you need strong, well-thought out, and when the system is changing, regularly refactored abstractions. You might not need a DSL but your class/type/trait designs needs to be sane, your API needs to be solid, etc ... DDD principles are key here.
- samatman 3y agoThe gradual type systems you're referring to are bolted onto the languages, or in Elixir's case, the runtime. If you want to see what a language with a deeply integrated gradual type system is like, take a look at Julia. I've found it to be both expressive and precise.
- weatherlight 3y agoHave you played at all with Gleam? https://gleam.run/cheatsheets/gleam-for-rust-users/ https://gleam.run/cheatsheets/gleam-for-rust-users/
- hoosieree 3y agoThis was my first thought too. I've not used it (just clicked through the tutorial) but it has a strong flavor like "Rust, but pleasant".
- rayiner 3y agoThe challenge of thought experiments, in a statically typed language, is ensuring soundness. The first version of Java Generics, for example, was unsound: https://hackernoon.com/java-is-unsound-28c84cb2b3f https://hackernoon.com/java-is-unsound-28c84cb2b3f
- jimbokun 3y agoIsn't Rust a "high level rust"?
- obeavs 3y agoFor what it's worth, Moonbit (https://www.moonbitlang.com/ https://www.moonbitlang.com/) is a really nice take on this. Designed by the guys who created Rescript for OCAML, but for WASM-first world.
- Diris 3y agoWow, that's nice. I didn't know about that one. Thank you for posting!