Extremist Programming (2012)
blog.ezyang.com
blog.ezyang.com
> I agree that extremism in order to learn is a great strategy.
I think it is key to consciously decide when you're learning and when you're doing, and to keep that in mind as you act.
If your goal is to learn, feel free to try bold stuff that might not work. But when your goal is to build, stick to boring stuff that you're confident will work.
This applies at all scales. When you're inventing a programming language, is it a scientific instrument or an engineering tool? When you're adding a feature, it is to understand the users or to deliver value to them? When you're changing the signature of a function, is it an experiment or an improvement?
Shipping can be quite "boring."
For example, I am about halfway through a social media app (90% of the way, if we include the backend).
The backend was written in PHP. I decided to do that, because it was an "all-purpose" open-source system, designed for low-budget orgs.
Also, I was already an experienced PHP programmer, and PHP is just fine as a server stack. It's not crazy good, but it works great.
The frontend is being written in Swift, which some companies might consider "edgy," but I'm using traditional UIKit, and storyboarding, which many folks would consider "clunky" (I'm supposed to use SwiftUI).
The thing is, is that SwiftUI is still trying on outfits, and the app is going to be very complex. I am not yet convinced that SwiftUI is "ripe" enough to do an app with the complexity I need.
That said, I want to learn SwiftUI this year, and explore its edges.
You just have to take measured risks, controlling the blast radius as appropriate in your context. But we have to be able to make progress as an industry, and that means taking risks when building real stuff.
30-60 minutes per day for months.
At first I produced some incredible garbage. But after a while, I learned how to take advantage of scaling the brush size, changing the opacity, manipulating color, until I was actually creating pretty cool stuff with the most unlikely tools.
By forcing myself to abuse the tools, I gained skills and insights that probably would have taken me years of "normal" use to acquire. And these skills weren't just a novelty - they could be applied even when I allowed myself to use the right tool (brush) for the right job.
Probably appeared first in ChiOS, circa 1968. "A bit is a file. An ordered collection of files is a a file..." UNIX did a lot of that, and variants on UNIX have taken it way too far. This idea keeps coming around.
Cons cells are awesome. What if we made a PL where everything was made of cons cells?
Lisp 1.5.
Mathematics is awesome. What if we made a PL where everything came from math?
APL, Mathematica.
Arrays are awesome. What if we made a PL where everything was an array?
Matlab.
Thinking about the evolution of programming languages more broadly, it's interesting to note that a lot of earlier languages were hyper focused on one set of concepts (notably objects in SmallTalk, and pure functions in Haskell but it applies to nearly all of them[0]). More recently though, there's been a move towards more of a mix-and-match and cross-paradigm approach. This can mean serious language bloat (any Scala programmers out there?) but, done well, it can also mean extremely helpful new ways to think about pragmatic code like with Rust's use of algebraic data types (enums).
I wonder if the next generation of programming languages will move even further away from arbitrary constraints as it becomes clearer which paradigms work best for which kinds of problems. For that to be the case, we'd have to become more domain focused and get over our obsessions with finding a universal unifying theory of programming.
Unfortunately at work we have SCRUM teams that practice this methodology religiously, but not on side projects. One team spent two months building a buggy functional wrapper around gRPC. When asked why- "We did it because it wasn't functional". The result is gobs of wasted cycles building overly complicated and abstracted garbage, and then further amortizing that over time with ongoing escalations.
I'm not sure how to help them gravitate away from shiny things to focus more on outcomes (simplicity, reliability, speed of delivery, meeting needs and creating value, etc..)
Let's make a PL without sigils...
Now...
What is the 'foo' that i'm reading? is it an $scalar? an @array? is it a %dict? a reference? an object? a función? a keyword?
IMHO terrible advice.
As somebody already posted in another comment, just be very clear on what you want to achieve. I'd also add that you must be very sure you can throw it all away afterwards.
It’s excellent advice.
Of those, C# only has static type checking. AFAIK C# does have some limited type inference (when using LINQ), but it’s nowhere near as powerful and ubiquitous as F#, where the following is completely valid:
let Add a b = a + b
and it will be inferred as: let Add (a:int) (b:int) : int = a + b
This also works in more complicated cases like when you’re accessing a property on a record, for instance.F# is much more than just C# with lambdas btw. If you want to write .net code in a functional style then F# is easily worth the time investment to learn.
let add x y = x + y
let f = add 2
Boom, now `f 4` evaluates to 6. I reckon that doing the same with C# would require a lot of boilerplate.(And I know I could have said `let f = (+) 2`, I just wanted to spell it out for those unfamiliar with F#)
Classes are awesome. What if we made a PL where everything was a class?
I mean, you can use lambdas, but last time I used C# you could still only use them inside a class definition.**Note: I haven't used C# in a while, do you guys have free functions yet? If so, ignore this post, my knowledge is just outdated.