Where static verification against a typechecker shines over runtime verification against a test suite is that a test suite can only demonstrate the presence of bugs; type systems demonstrate their absence (presuming of course that you understand how to encode certain invariants into your types and don't do some foolishness such as simply asserting all values as `any`).
Types can act as good documentation and as a safeguard for stupid mistakes. But the worst bugs are due to logic mistakes, wrong assumptions or non-foreseen corner cases. Here, either types do not help, or designing the type system is so difficult it is not worth the effort, and makes many future changes more difficult.
In my previous company we used Scala (with and without Spark) for everything, and this setup pretty much allows you both extremes. There was always a middle ground to be found, where types were expressive enough that they were useful, but not too much that they came in the way.
/s
Yeah, you're not guaranteeing correctness. There's a quote from automated testing discussions that applies here...
> You're not proving the system works. You're proving that system isn't broken in specific ways
Likewise, for a type system, it's guaranteeing the system is correct for the specific subset of "ways it can be incorrect" that the type system covers.
The rest of your comment I found to be a really good point in terms if feedback justification. The IDE checking your code before compile or runtime is faster than both. Good point.
For any more interesting properties (say "this function returns a sorted version of the input list", or "this function finds the smallest element in the set", or "this transaction is atomic"), you need something like dependent types, and that comes with a hell of a lot more work.
No type system can fix bad programming.
The point in the article is that when we read code we need another visualization to change or mental model. I can scan code and find most bugs fast, but when you are stuck a complexity by row/column sure would be handy to find overloaded assignments.
However, most people are using stuff like JS and Python. For them even the non-dependent type systems are an improvement.
Take the "basic" property "cannot be null" for example - Considering the issues and costs the lack of that one incurred over the decades, I'd call that one damn interesting.
And Rust? C'mon, its affine type system is its biggest raison d'etre.
On the premise of the article, maybe the key to representing a program visually is a very expressive (and strong) type system. There could be a way to derive some Visual Types from good old regular types, and diagram the visual types in any level of granularity one desires.
Just like visual programming, it looks like we are doing gradual typing very wrongly.
Doesn't Typescript offer seamless interoperability with vanilla Javascript?
If you are able to internalize everything, you are constantly simulating expectations in your head on what you are coding. Seeing where your expectations fall down on outputs is a valuable thing.
So, yes. If you fully understand everything already, the "paying it upfront" cost of exhaustive types is good. Amazing, even. Until you get there, you are almost certainly pushing off the feedback of learning where you do not fully understand the system.
Irony being what it is, most strongly typed programs that I have been introduced to were incredibly tight knots that were not easy to refactor. Many of the restrictions in the types would be far too strong from what was needed by the program, and refactors grow in difficult to explain ways.
This is all to say, the discourse here is fraught with nobody acknowledging that "well done" programs of near any paradigm/style are well done and work. Evidence is often used that languages that allow looser ideas are more numerous than those that don't. This ignores that lack of existing programs in the strongly typed world could also be lack of ability for many people to deliver using those practices at all. Which, in turn, ignores that that may be a trade off that is worthwhile in some industries. (I suspect it goes on.)
Eventually they did the same thing you can do in common lisp: Add so much metaprogramming that doublechecks invariants, it might as well be a compiled language.
One can make the case that a function can do the same. I agree, but a class is just a container for a set of related functions and state.
The problem with OOP seems to be that as a whole, devs are not that great at encapsulation and isolating domain logic.
Any sufficiently complicated Ruby program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Java
TypeScript compiler is too slow for hot module replacement so it’s used only for IDEs. During development, all transformation happens via esbuild/swc and is abstracted away with Vite https://vitejs.dev/
Download some horror show like Unkey and show a video of its millisecond hot reload…
If you tried and still think such a setup is not possible, send me an email (in profile) and I can do a 10-15 minute show&tell.
Or show me a non trivial open source ts project that’s instant; doesn’t exist and I have literally no clue why people keep defending this stuff; you didn’t make it right? I would be embarrassed but definitely not defending it.
https://www.kirandev.com/open-source-nextjs-projects-open-fo...
Even though I didn't measured the loading time, an effort has been made to accelerate everything that could be accelerated.
You don't need to resort to Lisp to get instant feedback. Try Dart - it's basically instant.
Rust I will give you...
My experience as an iOS developer has been mixed between places that use Interface Builder and those who create the UI in code. Something like Interface Builder is obviously a great idea for UI creation, which is why it survived so long and why Figma exists, but the actual tool itself (IB) isn't really useful for desigers who want one thing that works on all platforms. (Complaints like "xib and storyboard are hard to use with version control" miss the point; a UI designer shouldn't be seeing git-style text diffs anyway, they need a graphical diff).
Interface Builder is at least 5x faster than making the UI in code; one place in particular, I was making a native app by myself while a whole team was making a web app, and I wasn't simply keeping up with them, I also cought up the headstart they had built while I'd been assigned to a different project. The next place I joined a team and their app was a coded UI, and development was correspondingly slow. (Though how much of this is "teams are slower than solo developers" vs. my hypothesis is unclear to me).
My first coding job was before iOS existed, I was industrial placement student* in an academic research lab, and for that, my guess would be the best option mayhaps have been a mathematical formula WYSIWYG editor that output both latex and IDL.
* does this term get used outside the UK? What's the overlap between this and intern?
Question: how well does the interface builder thingy mix with interface in code?
Can you easily lay out the basics of an UI graphically and then add code where the builder is too limited for what you need?
Or it's the kind where if you start with the graphical builder you're stuck with just what the graphical builder can do?
https://www.youtube.com/watch?v=dl0CbKYUFTY
where they discuss how dragging/drawing allows one to make 80% of the app, and the balance of 20% is one's own code.
> The goal here is to literally eliminate 80% of the code that every developer has to write for their app - because it's in common with every other app. And let them focus on just the 20% of their code that's unique and value-add to their app. That's what this is all about.
---
A video of historical interest - OpenStep's Interface Builder in 1997, the year Steve Jobs returned to Apple.
It shows how forward-thinking NeXT was. Many of its innovative user interface concepts are relevant and in use today in different guises and interpretations.
> Every single app on NeXTSTEP was built using Interface Builder. It is the frosting on top of this object-oriented cake that we have called NeXTSTEP.
In the demo, Steve seems to use the word "object" with a depth of meaning closer to what Alan Kay explained, like independent (or rather interdependent) "cells" of software that communicate to each other via messages.
> OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.
On the Meaning of “Object-Oriented Programming” - http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay...
It's interesting that the Interface Builder was considered a "frosting" or visible representation of the underlying objects, which the users more or less directly created, edited, and connected together - without writing a line of code.
That ideal of user experience still hasn't been fully achieved to satisfaction, it feels. The ease and naturalness of creating software visually, as well as with other modalities, senses, medium of expression beyond text.
- allowed drawing a user interface as naturally as I used to use Altsys Virtuoso (or Macromedia Freehand which I moved to when my Cube stopped working)
- allowed programming the UI as naturally as HyperCard (and to a lesser extent Lisp) "clicked" for me
- was as visual as Google's Blockly (which as BlockSCAD: https://www.blockscad3d.com/editor/ I've used a fair bit)
- exposed variables in a mechanism like to OpenSCAD's Customizer: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Customize...
Currently plugging away with OpenSCAD Graph Editor: https://github.com/derkork/openscad-graph-editor but hoping that: http://nodezator.com/ will become a viable option (still a bit bummed that I rolled and crashed w/ https://ryven.org/ though in retrospect, maybe I should try to tie that latter in to: https://pythonscad.org/ )
The thing was shown to Steve Jobs and he hired its main developer, Jean-Marie Hulot.
This builder does look like a precursor to NeXT's and HyperCard too. I like that the "toolbox" appears next to the mouse, instead of having to go to the top menu or sidebar to select a new tool and back to position to use it. I missed that it ran on a Lisp processor, very cool!
And that the main developer later worked at NeXT and Apple.
> Jean-Marie Hullot authored important programs for the original Macintosh, NeXTSTEP and Mac OS X platforms. These include SOS Interface for the Mac, which later became Interface Builder for NeXTSTEP (1985), and later still evolved into an important part of Mac OS X.
> He also came up with the idea of the iPhone and led the iCal and iSync development teams for Mac OS X (2002).
https://en.wikipedia.org/wiki/Jean-Marie_Hullot
..Searching for "SOS Interface for the Mac", I guess it's Sophisticated Operating System, "the primary operating system of the Apple III computer" released in 1980.
Apple has two UI frameworks, UIKit and SwiftUI, and Xcode's Interface Builder handles each differently. The Interface Builder for each is built into Xcode, but the UI they present when editing is quite different — I'm unclear if they're both officially called "Interface Builder" or if people like me stuck with the same name for the new one because it's a thing for building interfaces.
The older system is UIKit, where Interface Builder produces some XML files — .xib or .storyboard — and once those are loaded, they result in objects which are fully manipulable in code.
The newer system, SwiftUI, the source code is the source-of-truth for a WYSIWYG editor — any change made in the editor immediately updates the code, any change in code immediately updates the editor. That said, in my experience at least, this editor falls over quite often if you do that.
> any change made in the editor immediately updates the code, any change in code immediately updates the editor.
Delphi memories :)
> That said, in my experience at least, this editor falls over quite often if you do that.
Not-Delphi memories.
Because java has a robust type system and yet I've never had any issue with it's compile times. And the parsing in the IDEs is so fast and good I can pretty much get all the feedback in real time.
Ah, that's the luxury of using a battle tested language that other people have invested billions of dollars of effort into optimizing.
Do you guys not have that in Rust and TS? Bummer man. Hope you get there someday. This is exactly why I abandoned scala btw.
You might define java as having a robust type system, but I would rate Rust's as significantly better. Several things in Rust I miss when working in Java:
* Monomorphized types
* Sum type and product types. Think sealed classes in java, but with better ergonomics
* A really clever type system that prevents things like ConcurrentModificationException and data races (not dead-locks or race conditions generally though).
Though, IIUC, Rust made early decisions about module structure that have really hindered compile speed, not necessarily tied to the type system.
Another big factor that makes rust slow would be optimizations & slow system linkers; it doesn't have a JVM that can warm up to optimize stuff.
Source: work with both Rust and Java on a daily basis.
Edit: The way the type system works out in general makes me far less worried about making sweeping changes in a Rust codebase than in a Java codebase, but there are still logic bugs that I miss occasionally. Still, it moves quite a big bug finding from "run the program and see" to "make it pass typechecking", which is quite a bit faster than compiling; you can typecheck Rust without compiling it.
Making your compiler fast is easy when it doesn't do any work. The Go one seems to be even faster than Javac.
Anyway, I'm not sure if this is a situation where the extra power of Rust's type system could not possibly be made more performant and it's just a natural tradeoff, or whether it's a thing where it's a matter of time before Rust (or some competitor) catches up and we can have it all
Are most people somehow working on giant repos?