Mojo is available for local download
modular.com
modular.com
Actually GPT is worse because they demand both a phone number and an email. Still haven't signed up because of that nonsense.
Programming playgrounds however are freely available for pretty much every mildly popular language, and these days many toolchains can even be compiled and run with JS or WASM so one could just serve some static files to host it. This is definitely more suspicious than what OpenAI and other ML companies are doing.
I appreciate you offering an alternative that preserves a small measure of privacy.
Over time we expect to open-source core parts of Mojo, such as the standard library. However, Mojo is still young, so we will continue to incubate it within Modular until more of its internal architecture is fleshed out. We don’t have an established plan for open-sourcing yet.
I read this as:"There are parts of Mojo that we are not planning to open source"
Which makes this a non-starter for me as well
Disclaimer: I work for Modular
What benefits does one get from starting off closed and transitioning to open source?
No open source--no attention.
Otherwise, you get stuff like the "Our Machinery" fiasco: https://www.reddit.com/r/gameenginedevs/comments/wd3o33/deve...
Most likely some beef with Autodesk.
Also I'm not sure whay JB is expecting in 5 years when he releases a paid version and all the languages that were inspired by it are more commonplace.
I had a few lines of python code, to count the fraction of A:s and C:s in a DNA (fasta) file adapted from [1]:
with open("chry_multiplied.fa") as infile:
a: int = 0
t: int = 0
g: int = 0
c: int = 0
for line in infile:
if line[0] != '>' and len(line) != line.count("N") + 1:
g += line.count("G")
c += line.count("C")
a += line.count("A")
t += line.count("T")
total_base_count = a + t + c + g
gc_count = g + c
gc_fraction = float(gc_count) / total_base_count
print( gc_fraction * 100 )
Result: $ mojo run gc.mojo
gc.mojo:1:6: error: use of unknown declaration 'open'
with open("chry_multiplied.fa") as infile:
...
"open" must be one of the most used Python functions ... :/https://docs.modular.com/mojo/manual/basics/#python-integrat...
i am friends/former co-workers with several people on the "team". doesn't mean i can't/won't/shouldn't call out startup hype when i see it. and again: the criticism has been borne out because this comment chain is off an example of an epic fail.
> This is pretty early in the development
you don't applaud someone that says they're going to do something just because they're fancy. like is this even up for debate? at such later date and time where they deliver i will be first in line to congratulate them (maybe even as a user) but not until then.
> I don't see hype they outlined a roadmap and are working on it.
they have been touting superset compatibility very loudly and then quietly writing conservative docs and roadmaps. you really don't see that or are you just bending over backwards to give them the benefit of the doubt?
> Not sure what fancy means in this context
you don't? then what exactly are you implying/suggesting here:
> Have you looked at the team?
moving on;
> Come to think of it I don't really remember Chris not delivering on a project.
already in my memory/experience (which is only a couple of years in this area): swift4TF and chisel (or FIRRTL or whatever). you can deflect and blame org charts or whatever but if you're gonna make the rounds on the talkshow/podcast circuit and take credit on the upside you gotta eat the blame on the downside.
i'm sure chris lattner is a great, smart, genius person. i'm sure everyone at modular is. i'm sure 100MM is a whole lot of runway to deliver. but they haven't delivered yet so their claims about being a superset and/or 35,000,000xxxxx perf gains are all (at least by me) taken with a grain of salt.
it wasn't
https://forums.fast.ai/t/where-is-the-future-of-fastai-swift...
> not paying enough attention to the fully compatible part as it's not something I personally care about
then maybe you shouldn't be bullying me into agreeing with you? dontcha think?
you're passing over a very crucial detail here: this person's opinion consisted solely of
> Have you looked at the team?
they themselves finally admitted it at the end. this isn't so much an opinion as hero worship at best and fanaticism at worst.
The thing that always gets me in these pissing contests is some random decides to wade in based purely on ____ and then when I point out ____ I'm the asshole. Like isn't it clear you just shouldn't have started making claims? Why am I in the wrong for knowing/understanding and demonstrating that understanding but you're not in the wrong for just guessing?
Responding with only "have you looked at the team?" with nothing to say about the current state of things, which was what the sidethread was about, is what probably set them off since it is actually a pretty patronizing thing to say.
You want to give more leeway to the team because you think they earned the cred. mathisfun123, not impressed by the details of certain past projects, is not going to hold their breath until the current state justifies the current hype.
Both are reasonable positions.
How Mojo gets a speedup over Python – Part 2 - https://news.ycombinator.com/item?id=37307260 - Aug 2023 (63 comments)
Mojo gets a speedup over Python – Part 1 - https://news.ycombinator.com/item?id=37294001 - Aug 2023 (3 comments)
Introduction to Mojo Language - https://news.ycombinator.com/item?id=37200400 - Aug 2023 (3 comments)
Guido van Rossum feedback to Chris Lattner on Mojo programming language [video] - https://news.ycombinator.com/item?id=36389804 - June 2023 (3 comments)
A first look at the Mojo language. as easy as Python, as fast as Rust - https://news.ycombinator.com/item?id=36289625 - June 2023 (1 comment)
Why use the new Mojo programming language? - https://news.ycombinator.com/item?id=35852734 - May 2023 (4 comments)
Mojo: The usability of Python with the performance of C - https://news.ycombinator.com/item?id=35825399 - May 2023 (45 comments)
Mojo – a new programming language for AI developers - https://news.ycombinator.com/item?id=35790367 - May 2023 (261 comments)
Chris Lattner and Modular Announce Mojo, a New Programming Language - https://news.ycombinator.com/item?id=35789890 - May 2023 (10 comments)
While it didn't get traction, it's a good interview which talks a lot about the language.
[1] https://www.modular.com/blog/mojo-a-journey-to-68-000x-speed...
Try to do it yourself (say take a merge sort implementation and try to make it scale), it'll be roughly this much after a few hours of work.
Now imagine the compiler is doing this for you.
You can have your python parts source compatible with the new language.
Of course they are far off from that.
But not that far off if your python code is typical ML framework consumer code.
It would be nice if it were open source, but I don’t see anything that’s unclear about the IP.
Community management and language feature haggling is not worth the expense at an early for-profit company with an alpha language that needs to solve internal problems.
I don't even understand how can Mojo be compared to Python without reflecting on Python Software Foundation which is arguably the main reason Python is such a wild success. We should do more PSF not less.
If their intent is to flesh out a basic product then open things up, then I take that back, but as of right now, they seem to be pitching it as "ready to go" based on the copy here. That's a lot of trust to put with them.
Last time this came up I found out they're actually using CPython to execute Python code, so I have no idea how you get a 22kB static binary out of it, unless that example is just pure Mojo and no Python.
Either way it definitely feels like they keep hammering the amazing "Python but good!" line without actually explaining how it works, which makes me a little suss. Like they're scared of explaining it because then they'll have to say the thing they aren't saying.
And this is next to the superset features they want to implement which currently seem to take all the manpower.
100mn is a lot of money, but a problem is that developers that can contribute in this space are rare and expensive. Not something any developer can do.
But hopefully I’m wrong and it is more than yet another “colony on Mars” story to attract interest and invested tots.
[1] https://modular.com/terms [2] https://github.com/modularml/mojo/blob/5823e1d9d176916c236c5...
Hopefully, someone will and sign up so that we know Modular intends to do with our data once they collect it.
https://docs.modular.com/mojo/faq.html#does-the-mojo-sdk-col...
For open sourcing, we also have a section in our FAQ: https://docs.modular.com/mojo/faq.html#open-source, and we answered a question about that in the latest livestream! https://www.youtube.com/watch?v=mQh9es5gfpo
For the question on pricing, the Mojo SDK is free to use.
Disclaimer: I work for Modular
1. Getting paid to work on ML to such an extent that perf is important (enough)
2. Comfortable leaving the warm confines of python and a huge ecosystem
3. Willing to learn a brand new, closed source, beta maturity language
4. Does inference on CPU
5. Willing to run their inference pipeline behind some FaaS layer because that's how I'm assuming modular plans to make money? The alternative is an honest to goodness licensed compiler and that seems even more farfetched (though I guess not beyond the realm of possibility).
What I wouldn't give to be in the room when they're pitching VCs because they've managed to raise a lot of money for what looks like a TAM of like 5 people.
Faster, yes, but at what cost?
I'm so impressed by the Python community, but I'll never quite understand why they gravitated to... Python itself. It's unbelievable to me that in Mojo's case some of the brightest, most famous engineers have gathered to do incredible computer science work to improve the compute performance of a language that is fundamentally flawed in its performance characteristics for those very applications. It just seems like such a waste.
How on earth did we arrive at this moment?
Chris Lattner is right in his Lex interview: he had to accept that the community was already committed to Python and given that reality, that in turn pre-filtered his available paths. But my god, what if the community had gravitated to a better language [for these purposes] in the first place? How much further along would we be in our tooling and capabilities to deliver value?
Chris, who I admire, loves to talk about language design decisions; loves to talk about how thoughtful they were in the decision-making around Swift; and then in the next breath says, hey whitespace-based scoping doesn't matter, don't worry about these things. Chris all you do is worry about these things, and worry about them for Mojo. He clearly has opinions that he masks about design choices Python has made; otherwise, after all, why the need to make Mojo?
It just seems like at the end of the day, Mojo may be the most technologically advanced lipstick ever to be placed on a pig.
(Edit for grammar, but clearly not for brevity or conciseness. XD)
Better in what regard? Performance? Maybe there are more important things than performance, like ease of use and barriers to entry.
People in this space already tackle essentially complex problems, don't throw more accidental complexity in the form of "better" or more performant languages/APIs.
Based on Python's slow and steady incresae, timing and luck don't seem like good factors for explaining its popularity. The others are debatable though.
[0]
https://flatironschool.com/blog/python-popularity-the-rise-o...
Luck is harder to quantify, but at the very least competitors like common lisp didn't have much of it.
Language wars have been forever, of course. But for a few years around 2010-ish, practically every single thread would have someone bringing up Python. If the post was about a tool, how the thing should have really been written in Python. If it was a how-to tutorial about a feature in another language, there would be a subthread about how Python undeniably does it better. Not occasionally, in a thread here and there - it was to the extent you couldn't miss it even if you wanted to. That's a kind of marketing that's proven effective in a forum like this, which is why it's being replicated by other languages now.
It seems like there are some potential candidates with improvements in dimension X, but nothing that is an obvious alternative.
Braces are strictly worse than whitespace indentation for several reasons. Brace-based languages:
1) Generally have the "dangling else" set of ambiguities. 2) Some (e.g. C) allow but do not require braces which leads to style debates. The ones that require braces are more verbose. 3) Require more punctuation clutter, and consume more vertical whitespace in practice. 4) ... use braces that are completely redundant with indentation in practice!
It's super funny to see people defend curly based languages. Using curlies but not indenting properly is almost always a sign of a bug (e.g. clang has warnings for this sort of thing due to the "goto fail" and other debacles.
That said, as you also know, Python compat is not optional for us, so Mojo doesn't actually a choice at all here. I find it amusing though that your post acknowledges thoughtfulness in language design and thinks this is an example of a lapse of judgement. :P
-Chris
Well, that's because they're not really "strictly worse" in every way. I find curly braces helpful for readability and cursor navigation. The latter is only possible with Python by completely parsing the code. Also I don't like reading vertically dense code, so having (almost) empty lines inbetween is fine. All subjective of course, but that's the case for every aspect of language syntax.
> Using curlies but not indenting properly is almost always a sign of a bug
I don't think anyone criticising Python's syntax cares about the freedom to have inconsistent indentation, that's not the point.
Ha! I love your reply. Thank you.
I know you care about language design. As I said more or less, that's self-evident, and I'm sorry for taking your whitespace comments too literally. You're the source, after all, not me, so accept my apologies there. It's misinterpretation, but not meant to be a misrepresentation. :-)
My comment wasn't meant to be critical of you. Honestly, as a pretty famous engineer, it never even crossed my mind you might read my message. As I said, I know you have to deal with reality to accomplish your goal, and that reality existed before you showed up to take on the challenge.
Thank you for all your contributions and good luck on Mojo.
Chris
Python is fantastic at lashing things together, and most programming is combining pre-existing functionality.
As someone that started to use python for science relatively soon (before numpy), I have to ask: which better language was existing at this time ?
sure would be nice if this was front and center on the actual website; the download page requires the user create an account in order to even find out that linux is the only supported platform at present.
Edit: Now I have Austin Powers stuck in my head when I see Mojo
Sure if something similar happened to an open-source project, you would still have to either hire engineers to work on the compiler/tooling/language or to rewrite it in a more supported language, but I would consider it a little less riskier as you aren't dependent on one vendor
Not with that kind of honesty, but call it a product/framework/partner for automatically optimizing in-house python code or something like that, and it sails right through.
Who doesn’t want a 68.000x speed-up!
1. Just because something is OSS doesn't mean the public is entitled to defining the roadmap or design decisions. If you set working norms up front and make it clear who has decision-making power and why, people will decide for themselves if they want to engage or not. A lot of frustration in OSS comes from lack of clear boundaries around how and why something evolves the way it does.
2. You can meet in the middle and be source-open. Don't use an OSI license, don't guarantee that you'll look at a community contribution, and don't guarantee that you'll engage on a particular issue. People can still benefit from seeing the source and deciding on if it's the right tool for them.
I know a lot of folks rag on "corporate controlled OSS", but there's a lot of examples of that motion working really well for products. I hope Mojo does this eventually.
https://docs.hidet.org/stable/gallery/developer-guides/hidet...
Wrote a quick blog post on it here: https://www.polarsignals.com/blog/posts/2023/09/07/profiling...
It honestly feels a lot like writing C++ with Python syntax. Still a lot missing, but excited to see where it goes.
[0] https://www.youtube.com/watch?v=qCGofLIzX6g [1] https://discuss.python.org/t/mojo-python-with-c-gpu-performa...
For data science and machine learning, they are two type of programmers namely A and B type, for analysis and building respectively [1]. The former are mostly analysts, scientists or mathematicians that are mainly non-programmer and the B are hardcore programmer that build engine, library, systems and sometime for real-time processing for example embedded signal processing.
For the former, their programming bias are closer to pseudo code and naturally they inclined more towards intuitive programming languages for examples Python and Matlab. For the latter, however, they are mainly library and system builders with real-time bias and their favorite tool are C, C++ and perhaps Rust.
Essentially, Type A prefer easy, low barrier and intuitive languages where real-time is not necessary, while on the other hand Type B required real-time functionality and efficiency regardless of language programming complexity.
From the beginning of programming time, none of the programming languages can really satisfy both types, and that's the main reason Fortran, C and C++ based library are still being widely used by Python, Matlab and Julia, case in point namely LAPACK/BLAS, Eigen and FTTW. D, however, is more than capable of matching and replacing these traditional powerhouse libraries since seven years ago with its Mir equivalent and D should easily satisfy the Type B crowd [3]. Heck you can even write bare metal system without OS with it [4]. Meanwhile, writing bare metal in Julia probably not a very good idea [5].
The harder is to satisfy is the type B crowd and unlike Type B they're fast becoming majority users of the programming languages and this is manifest by the increasing popularity of Python language. For further reading, I'd highly recommend this Ask HN threads on Why did Python win [6].
This is where D language come into the picture, and apparently with D you can have your cake and eat it too [7]. D creators have cleverly make the language has default GC despite extreme disagreement from Type A crowd and they will let you know every time D is mentioned anywhere in the public forum. However, they're kind of missing the big picture since they are fast becoming the vocal minority and most if not all of their requirements can be met with D as proven by Mir [3]. Not only this, D creators also banned macro from the language so D does not have the same fate as Ruby where some Rubyists considered RoR as a ghetto although it's extremely popular and probably the main reason why people is using Ruby in the first place [8].
D seems to hits the sweet spot in becoming the Goldilocks of programming language and it's already an open and mature language that's included in GCC eco-system. Ultimately D need to appeal to the Type A data scientists and this where D creators has gone out of their way to make D as intuitive and Pythonic as possible. In their paper on "Seven Deadly Sins of Introductory Programming Language Design", where these Monash university professors analyzed these popular programming languages back in the day (1996) for their suitability in introductory programming language design namely ABC, Ada, C, C++, Eiffel, Haskell, LISP, Modula 3, Pascal, Prolog, Scheme and Turing [9]. It's a shame that Python is not included because back in 1996 when the paper was written it's still in infancy and not popular as today. Personally, I'd add that not adding a GC as the 8th major or deadly sins of the introductory programming language but it's probably just me. I'm pretty sure that D language authors and designers did not read this seminal paper when they're designing D (I know I asked), but it seems to follow this natural and universal guiding principles that I hope Mojo authors and designers, and other programming languages, will heed as well.
[1] There are two types of data scientists - and two types of problems to solve:
https://medium.com/@jamesdensmore/there-are-two-types-of-dat...
[2] List of numerical libraries:
https://en.wikipedia.org/wiki/List_of_numerical_libraries
[3] Numeric age for D: Mir GLAS is faster than OpenBLAS and Eigen
http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
[4] Writing a bare-metal RISC-V application in D:
https://news.ycombinator.com/item?id=37346218
[5] Running Julia bare-metal on an Arduino:
https://news.ycombinator.com/item?id=31481895
[6] Ask HN: Why did Python win?
https://news.ycombinator.com/item?id=37308747
[7] Why I use the D programming language for scripting:
https://news.ycombinator.com/item?id=36928485
[8] Stop Designing Languages. Write Libraries Instead:
https://lbstanza.org/purpose_of_programming_languages.html
[9] Seven Deadly Sins of Introductory Programming Language Design:
https://users.monash.edu/~damian/papers/PDF/SevenDeadlySins....
Some problems off the top of my head:
- The lack of new variable declaration keyword makes scopes less explicit. nonlocal is not simpler in the large than `let x = ...`
- The lack of multi-line lambdas is very limiting for anyone coming from JS, C#, Rust, Kotlin... heck even Java
- The ternary operator (... if ... else ...) is needlessly different for other mainstream languages
- I’ve used nonlocal 0 times ever.
- I get that people miss them, but you can define nested functions if you want. Nameless functions are nifty, but I’ve never lost sleep over putting `def foo` in front of what would’ve been a lambda in other languages.
- I kinda like the Python ternaries.
Preferences are A-OK, and I’m not saying you’re wrong. Just chiming in that the things you mention aren’t universally disliked.
Same here, but I got bitten by weird scoping rules quite a few times.
Separating variable definition from assignment (e.g. with 'let') would probably help a lot in this case.
Because it's consistent and people don't want to relearn minor details each time they switch. And Python has a lot of those little differences. Though the "and" and "or" keywords are among the few things I actually like.
> meanwhile for the most part anyone can understand Python syntax
What matters more to me is how the syntax works in the long term. I have no trouble reading and writing a lot of Rust code, but even after years with Python I still can't remember the difference between "[-1:]", "[1:]", "[:1]" etc for slicing lists/strings. Recursive list comprehensions with their lack of parentheses are unreadable to me to this day (e.g.: `[item for sublist in list_of_lists for item in sublist]`). Python is very easy and quick to pick up, really productive for prototyping, but I don't consider its syntax to be its big advantage.
> Recursive list comprehensions with their lack of parentheses are unreadable to me to this day (e.g.: `[item for sublist in list_of_lists for item in sublist]`)
1. there's no recursion here
2. it's literally just a double nested loop flattened (i.e. exactly matching the semantics) to be on the same line instead of indented and on two lines:
[item for sublist in list_of_lists for item in sublist]
is the same as for sublist in list_of_lists:
for item in sublist:
item
like why would you need parens when you know the for starts the next nested loop.Well that's the thing, I don't know the "for" starts the next nested loop because there's no indicator for that, and aside from that it's harder to see it at a glance. Nested loops have a colon, line break and deeper indentation inbetween, here you get nothing.
To me it feels like it breaks Python's own rules: the language omits curly braces for scopes but ensures readability with colon & indentation. But here the chained list comprehension nests two loops without any visible scope boundaries.
Perhaps it's just me and others can read it just fine, but that's my two cents on it.
`for` is a keyword in the language - you know that the `for` starts the next loop by the same reason you know `for` starts any loop.
The remainder of your complaint makes zero sense. You expect us to sympathize with an archetype (you) that is familiar enough with the language to know what a `for` loop is (basically week 1) but not familiar enough to spot the keyword. This is an archetype with zero instantiations (ie I'm calling bs on even you personally experiencing this problem).
the goal posts have been moved; your comment:
> I don't know the "for" starts the next nested loop because there's no indicator for that
my point: there is no other role that the sequence of characters `for` can play in python (because it's a keyword) so you have all indication that you need.
In other words, I don’t think this is about the syntax at all
Another big issue is that it's not expression based. For example you can't do `foo = (yield a).b` you have to do `x = yield a; foo = x.b`.
Having a special syntax for the expression version of if else is another example as you said.
I was disappointed to discover Dart made the same mistake there. There's a totally different syntax for match statements and match expressions. Why?? Ok maybe backwards compatibility.. but still. They fixed nullability properly and it wasn't too bad.
The first snippet actually works fine. Yield expressions were introduced with PEP 342 in Python 2.5.
x = [yield a for a in b]
Which yields (heh) an `Invalid Syntax` error. Thanks for the link to that PEP though - turns out the answer is that you almost always have to parenthesise it. x = [(yield a) for a in b]
> SyntaxError: yield inside list comprehensionOk my original point stands.
Also, I didn't say it was impossible to navigate, but it is cumbersome and annoying. Forced whitespace sucks.
The ONLY piece of information that is available to you regardless of how deep you are into a function is INDENTATION. Your curly braces won't help you.
Besides that, you should seriously reconsider your coding style if this is an actual problem for you.
...No? It sounds like you write very long, messy code blocks. Consider the following example, I will write a nested loop in 2 languages:
In Python:
for _ in range(10):
for _ in range(10):
print("Inner")
print("Outer")
Here's something similar in JS: for (const _ of foo) {
for (const _ of foo) {
console.log("Inner");
}
console.log("Outer");
}
In isolation, while I'm writing this comment, I would say these code blocks are equally easy to parse. In the context of frantically debugging, scurrying around a file, I may (and have!) missed the indentation difference in the Python example.Curly braces allow me to have 3 visual indicators that a block is finished: a visual text object (the brace itself), an extra line separator (the closing brace lives on its own line), and indentation. In Python, I only have one of those things (just indentation). I can have 2 (indentation + line sparation) if I always insert a newline before `print("Outer")`, but empty lines can get deleted and I may forget to include them as I write code. You'd need to configure a linter to guarantee the line separation indicator in a language that delimits scopes by whitespace.
Obviously. You're using 2 spaces indentation for Python and 4 for JS. Don't be surprised that it is harder to see the indentation.
I think I might have indentation related bug early on, when I was new to Python, but I don't remember any recently. It could be that Python 2 allowed to mix tabs and spaces for indentation, while this is no longer allowed in 3.
Also this is how I would format the code:
for _ in range(10):
for _ in range(10):
print("Inner")
print("Outer")* try catch is different keywords from virtually all other languages.
* walrus tusks, the general order in list comprehensions generally where bindings come after expression
* typing is awful, unsound in a lot of cases, there’s a ton of special non straightforward plugins in mypy. This is partially better in pyright but not considerably.
* package management is silly. Poetry is like a poor imitation of npm. Venvs are a pain in the butt.
… all of this for a pretty slow language.
Python : try/except/finally/else
C# : try/catch/finally (no equivalent of “else”)
VB.net : try/catch/finally (no equivalent of “else”)
JavaScript : try/catch/finally (no equivalent of “else”)
Java : try/catch/finally (no equivalent of “else”)
Ruby: begin/rescue/ensure (no equivalent of “else”)
C++: try/catch (no equivalent of “finally” or “else”)
Python’s try/except/finally/else seem to use nearly the same keywords as many other popular languages (Ruby is an oddball here, using similar semantics with different keywords), except that it uses “except” in place of “catch”, and “else” is a unique feature, and C++ lacks “finally”.
EDIT: The above has been edited throughout to correct an initial thinko that had Python using the common “catch” instead of “except”, which I really can’t explain because I've been wading throw Python exception handling code a lot recently.
It can also be used postfixed to a statement that might raise an exception.
Ruby is oddball here because it's subtly different.
def a_method
@value = dangerous_method_call rescue "default value in case of exception"
do_something_else @value
rescue
puts "an error, oh no"
endtl;dr:
1. This is my biggest issue with Python.
2. Are there any tolerable solutions you've found?
3. Are there any non-Python languages you'd recommend?
The root of Python's typing issues seems to be ad-hoc syntax recycling as a stand-in for a thoroughly planned type system. Understandably, Guido and others advise using Protocol types to make up for earlier design decisions. It sort of works, but:
1. It's effectively an unspoken deprecation for parts of the standard library
2. Current design choices create new problems
3. It still doesn't reliably prevent runtime errors
Things break down further as you move beyond the built-ins:
1. Pydantic and other tools come with their own problems
2. Ugly things happen at boundary lines in APIs (ctypes vs OOP)
3. All of these get even worse as Sphinx gets involved
The last two items came up in a recent PR discussion. The other commenter's point seemed correct: simple, specific, and rigid types prevent problems. But then why should we have Generic and Union at all?
I'm still going to use Python when necessary, but it makes the grass look very green near languages like OCaml and Elm. If Rider can make .NET's packaging tolerable, maybe F# would be good too. Are there any others you'd suggest?
You can declare variables (such as x in the above main() function) with var to create a mutable value, or with let to create an immutable value.