[1] https://www.tedinski.com/2018/03/20/wizarding-vs-engineering...
[1] https://www.tedinski.com/2018/03/20/wizarding-vs-engineering...
This is precisely what gradually typed languages — like TypeScript, Flow, and typed Pythons — solve!
I talked about this on Software Engineering Radio last week: https://www.se-radio.net/2019/10/episode-384-boris-cherny-on....
You have the madness of thousand of developers flinging code at the universe due to the easiness of browsers, JS, and npm.
This results in great speed, but not great quality.
When your project/company now wants quality, you keep your code but transition to types. (In OSS space, Angular and Yarn projects have both done JS => TS migrations of some form.)
> A caller can change sync function to async, breaking the functionality downstream.
I think you mean callee?
Are you taking about using a returned result? Because most languages permit ignoring return values.
If you want to check out promise use, check out https://tsetse.info/must-use-promises
Consider
``` const myIntValue = f(); ```
This code will silently break when f changes from sync to async.
const myIntValue = f()
// Error TS2365: Operator '+' cannot be applied to types 'Promise<number>' and '2'
const myResult = myIntValue + 2
async function f() {
return 42
}I have heard good a stuff about "gradulizer" though. It uses a gradual type system instead of dialyzers success typing.
Without specs, it will assume every type is 'any()', unless it has information to infer something more stringent. For instance, if it sees you add 5 to it somewhere, it will instead assume it is a number. Etc. Even if in practice it actually is a list of some kind (and so that addition of 5 will fail). Which, yes, ain't great. Hence why I said it was a gradual transition; it will catch provable errors (i.e., if you call append on that same variable as above, it will note that there is no type that allows both append, and + an integer, and error), but leave plenty of things uncaught that could have been caught had it known the type in question (via a type spec).
I’ve never worked on a program so small that readability didn’t matter. I consider it a crucial ingredient of expressiveness and development speed.
Though your perspective could explain a few of the more atrocious code bases I’ve seen.
There's two many people that have swallowed SOLID whole and can no longer see good engineering as a trade-off against other factors.
For example, being strict about having the smallest possible public API and making most methods private protects me from future breakage that might never be an issue (I might never upgrade) but forces me copy/paste vast globs of your code into my own if I need access to something you didn't anticipate. (and that's assuming I have access to your source. Worst case is that I have to reimplement things that already exist in the code I'm interfacing with)
Python got this right. Private methods are a weak or strong hint that you might want to think twice before calling them. But you're the boss at the end of the day.
I think this is why it's easy to point a thousand things built in python which people use every day (like instagram), while in, say, haskell, there are barely a handful (pandoc, facebook spam filter, etc.).
[0] https://martinfowler.com/bliki/DesignStaminaHypothesis.html
I've never heard of this before... I love it. Thanks for bringing this up.
I'm not familiar with this use of the term "expressiveness".
My understanding is that expressiveness (as per "On the expressive power of programming languages", Felleisen 1991 [0]) has to do with capabilities that a language has that separate it from another language. C is more expressive than Python in that it gives you direct access to memory management, whereas Python is more expressive than C in that it provides inheritance/OO. (These are just examples.)
Type safety, performance, and readability are all wholly separate from expressiveness, I think. A language's type system and performance benchmarks have nothing to do with the expressive power of a language outright, and "readability" is entirely subjective to begin with.
So: would you mind elaborating on what you mean, exactly, by "expressiveness of [a] language" here?
---
In fact, most of what you (and the linked article) are talking about has to do with the dynamic/static spectrum, not this "wizarding/engineering" spectrum you've coined (though I do kind of like the idea of that for discussing development methodologies).
The article is all about how the dynamically-typed nature of Python allowed for rapid iteration at the beginning of the Instagram project, but has since hindered further progress as they've grown larger. But now they feel they can't just rewrite it all in a statically-typed language because of the engineering overhead involved.
On this note, I want to go to your last point:
> I wish there was a language that let you move gradually from one end to the other, exactly when you need to.
With regard to the dynamic/static distinction, there are languages that allow you to move "gradually from one end to the other", and they are (aptly) called gradually-typed languages.
Gradual typing was invented by Jeremy Siek and his PhD student, Walid Taha, back in the mid-2000s at Indiana [1]. In this discipline, you can have a statically-typed codebase with local dynamically-typed regions. You get all of the static guarantees for everywhere that they can be made, and dynamic regions impose runtime checks to ensure consistency. (This connects closely to contracts, which are primarily worked on by Robby Findler at Northwestern, I think.)
Unfortunately (to me), it seems like a lot of these languages are implemented in terms of existing dynamically-typed languages. For example, Sam Tobin-Hochstadt (Indiana) created Typed Racket, which is (of course) built upon Racket but provides a gradual typing discipline. Wherever possible, static types are checked, and everywhere else utilizes contracts to guarantee runtime consistency.
Anyway, all this is to say: the technology exists, technically, but is in its infancy. There's no doubt it'll be some time before it sees widespread use throughout industry. Sam wrote up a brief overview for the SIGPLAN Perspectives blog recently, if you're interested [2].
[0] https://www.sciencedirect.com/science/article/pii/0167642391...
[1] https://wphomes.soic.indiana.edu/jsiek/what-is-gradual-typin...
[2] https://blog.sigplan.org/2019/07/12/gradual-typing-theory-pr...
I find that pythons OOP + functional aspects, combined with a good understanding of the language hits a sweet spot here. One that simply can't be reached in c/cpp/go/java/haskell, and which is much easier to reach than in js/rust/other langs where I think it is possible.
The wizarding/engineering spectrum was coined by the article I've linked to[2]. I think the post is exactly about that, first Instagram was wizarding and they had a suitable language for wizarding, now they're engineering, but their language is still only good for wizarding.
As I've said in a sister comment, it's not just about static typing, but metaprogramming/macros/side effects everywhere etc. There's more to the expressiveness/powerfulness than just types. While gradual typing is certainly an improvement, I think we need more research in this direction.
Java projects get done all the time.
Additionally, even though it isn't standard Java, I have plenty of new apps running on my pocket.
Google does all kind of new Java work (Golang contrary to myth, is just one of the languages Google uses for internal stuff, and niche at that), Amazon of course, most of Apple's backend services are Java, Twitter, AirBnB, Uber, LinkedIn, TripAdvisor, and tons of others use Java, and write green stuff in it all the time...
In what parallel universe is not Java immensely popular or not used for green projects?
It is a fools errand to think Kotlin/Native would ever overtake Java.
Only on Android it might have a future, if Fuchsia never becomes a thing.
On what concerns the JVM, Kotlin hype will be over in a couple of years, and it will get as much use as Scala, Clojure, Beanshell, Groovy enjoy nowadays.
Guest languages never get to own a platform, and with time all platform languages end up getting enough features that the large majority of developers never bother with extra tooling, debugging layer and idiomatic wrapper libraries of the guest languages.
And we know that because?
>Guest languages never get to own a platform
That depends on the platform, who is running it, and how. You couldn't have a worse steering than Oracle.
And most "guest languages" are smaller affairs, they don't have companies the size of Google chosing them for Android app development (a huge niche in itself). Or have first class support from the most popular IDE of the host environment.
Plus, anything is anecdotal, as we have so few cases of major parent/host language rivalries, and even fewer cases with similar dynamics, that there's no real prediction.
Scala was too complex for most Jave-ers, too slow to compile, didn't have a Google pushing it to its platform devs but an insignificant company, etc. Clojure was a Lisp (= doomed), Beanshell and Groovy where from small, insignificant origins, and not pushed by anyone really mainstream the size of Google/FB/etc.
Kotlin doesn't have any of those issues.
Heck, even Elixir does quite well I hear.
UNIX and C, Web and JavaScript, Windows and .NET/C++, macOS and Objective-C/Swift, Android and J̶a̶v̶a̶/Kotlin/C++....
Google only cares to push Kotlin on Android, and it only matters because Google visibly doesn't want to move Java beyond the Java 8 subset that Android currently supports, so the choice is between an handicapped Java support or Kotlin.
Until there is a JVM written in Kotlin, and Kotlin gets first class support in all Java IDEs instead being a tool to sell InteliJ licenses, it is just yet another language that happens to target the JVM.
This ignoring that Kotlin already has a couple of impedance mismatches with the JVM, sequences vs streams, lambdas vs SAM, co-routines vs fibers, inline classes vs data classes.
Elixir is doing well because many developers seem wary to learn Prolog/Erlang syntax.
They do up to the point where they differ philosophically. Java is never going to turn in to a Clojure, nor is it going to adopt the type of dynamic scripting features Groovy offers.
Kotlin and Scala are more at risk in that way.
Why any enterprise would use C++ for standard "business" or "large scale" programming makes no sense to me.
Enterprises want stability, not speed to market. Most of their infrastructure changes slowly (as in features deployed once or twice a year maybe). They have stable support mechanisms for this, including long and complex processes of approval.
So while you might not write it as full stack C++, a couple of native libraries might be required as dependency, to access OS features, give some help to the AOT/JIT compilers, or in Java's case implementation of more machine friendly data structures.
I'm not a fan of the language, but java has a huge number of developers, a rich mature ecosystem of software and is quite productive (enterprise patterns aside), it's a good sweet spot for most companies.
C++ is a hydra of complexity, sure it has it's place, but it's not nearly as productive as Java for your typical web application.
Go is almost the opposite, so simple it lacks features like generics. The last time I used Go it had fundamental usability issues around dependency management(although I think recent versions have improved on vendoring a little).
Modern C++ well is as productive ( probably even more productive ) as Java. The main issue with C++ is recruitment, C++ engineers are rare because C++ is barely teached.
Just like MISRA tries to constrain C programmers from doing dumb things in the embedded world, "modern" C++ tries to the same in the business world. But there isn't an easy way to enforce it, especially when you're outsourcing to some code sweatshop.
Every mature enough language has a subset that you need to avoid. Including Java. This is precisely due to this kind of things that every company need to have coding guidelines and proper static analysis tools.
> especially when you're outsourcing to some code sweatshop.
If you outsource your dev to cheap, other side of the world, low quality engineers. Then you deserve your problem, in any language.
I worked in the past for a company (embedded programming) that had an entire team of expensive engineers in Luxembourg just to fix the stupidities of an other team of outsourced engineers in India.
The problem with modern C++ is having many devs to actually make use of it.
Many devs don't care to follow up on modern language X best practices, rather just typing away something that works.
Too many companies need devs but have engineers, or they need engineers but only have devs :/
(Except those people who claim software engineers aren’t real engineers)