Fri Jun 20 06:06:15 PM +08 2025 #61 ✎
fn main() {
println!("hello, world");
}
code highlighting is cool
fn main() {
println!("hello, world");
}
code highlighting is cool
N.Wirth. Algorithms and Data Structures. Oberon version Harold Abelson, Gerald Jay Sussman, Julie Sussman. Structure and Interpretation of Computer Programs
ken-and-den.jpeg
«Мы постоянно меняемся и очень важно помнить о том, что ты был положительным персонажем» Бараш
First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.
Start ridiculously small (a single pushup or one minute of meditation) Attach new behaviors to existing routines (meditate after brushing teeth) Celebrate immediate small wins to reinforce the behavior Focus on consistency rather than perfection Design your environment to make good habits easier and bad habits harder
Cultivating positive habits provides a powerful mechanism for life improvement. Regular exercise represents a classic example—initially challenging to establish but relatively easy to maintain once integrated into your routine. This principle applies equally to reading, writing, meditation, or other beneficial practices. With exercise specifically, I personally reject the concept of scheduled rest days because they tend to multiply into extended inactivity periods. Instead, I find daily movement more sustainable, even if it’s minimal, adjusting intensity according to energy levels and recovery needs.
This book is dedicated, in respect and admiration, to the spirit that lives in the computer. ``I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.'' Alan J. Perlis (April 1, 1922-February 7, 1990)
Wega
IBM System/360
Embrace object-oriented patterns for organization. For organizing larger parts of your application, consider object-oriented constructs. Using structs or enums can encapsulate related data and functions, providing a clear structure without worrying about the details. Leverage functional patterns for data transformations. Especially within smaller scopes like functions and closures, functional methods such as mapping, filtering, or reducing can make your code both concise and clear. Use functional programming when you can phrase your problem as a series of transformations over some data.} Use imperative style for granular control. In scenarios where you’re working close to the hardware, or when you need explicit step-by-step execution, the imperative style is often a necessity. It allows for precise control over operations, especially with mutable data. This style can be particularly useful in performance-critical sections or when interfacing with external systems where exact sequencing matters. However, always weigh its performance gains against potential readability trade-offs. If possible, encapsulate imperative code within a limited scope. Prioritize readability and maintainability. Regardless of your chosen paradigm, always write code that’s straightforward and easy to maintain. It benefits not only your future self, but also your colleagues who might work on the same codebase. Avoid premature optimization. Don’t prematurely optimize for performance at the cost of readability. The real bottleneck might be elsewhere. Measure first, then optimize. Elegant solutions can be turned into fast ones, but the reverse is not always true.
«Как правило, одиночество вокруг нас — это плод нашего воображения, а на самом деле жизнь вокруг нас бьет ключом, в ожидании когда мы вольемся в её шумный поток» КарКарыч
108. Проектируйте структуры данных в последнюю очередь. Добавление полей данных выполняется в процессе проектирования в последнюю очередь. Другими словами, после того, как вы разработали сообщения, вам нужно понять, как реализовать возможности, запрашиваемые этими сообщениями. Вероятно, это труднейшая часть процесса объектно-ориентированного проектирования для структурного программиста: заставить себя не думать о лежащей в основе структуре данных до тех пор, пока не будет готовы полностью система обмена сообщениями и иерархия классов. В этот момент процесса проектирования вы также добавляете закрытые (private) "рабочие" (или "вспомогательные") функции, которые помогают обработчикам сообщений справиться со своей работой.
Still, the history of mainstream programming languages is essentially a story of programmers vocally and emphatically rejecting what eventually proved to be some of the most incredibly successful innovations in the history of the field. Assembly programmers largely laughed at FORTRAN, but just a few decades later, there were nevertheless very few remaining assembly programmers. First-class functions were widely derided as needlessly complicated and confusing until programmers were forced to finally take the time to learn to use them once JavaScript became a load-bearing language by historical accident, and within a decade, they became a required feature for every major programming system. Sophisticated type systems largely retain a perception of overengineered, ivory-tower elitism, but many of the programmers who hold those very opinions have enthusiastically adopted Rust, a language that features a type system so complex that idiomatic Rust code can easily put Haskell programs to shame.
The essential, most stubborn problems in programming languages come from unavoidable tensions between conflicting desires and requirements. We want loosely coupled software components that can be easily reused, but we also want the performance benefits of tight coupling and specialization. We want flexible programming languages that do not impose upon our freedom of expression, but we also want the benefits of static program analysis and powerful safety guarantees. We want sophisticated type systems that allow specifying ever more complex invariants, but we also want readable type signatures that won’t regularly end up longer than the code itself.
https://en.wikipedia.org/wiki/Sales_(band)
Functional programming allows a programmer to express ideas in an inherently mathematical way. This makes FP great for things like mathematical proofs, or great for people with a mathematical background who struggle to think like a programmer. It also simplifies code - if I'm reading a function with zero side-effects, or zero mutation of some data structure, then I can very clearly see the input, transformation and output. This style of function should be prioritised where appropriate, even in a procedural language like C. Reducing cognitive load for a programmer is clearly a bonus.
The difference may not seem drastic, but the compounding performance returns will be vital in applications like simulations, games, and real-time systems where each CPU cycle is gold-dust, and each cache miss a deterrent to having a great product. So, in a well-written program, an engineer may make use of SoA for field-wise operations, and AoS for entity-wise operations.
Feeling stronger
$ python benchpop.py Size: 1000 - With: 0.0015s, 10318 comps | Without: 0.0018s, 16850 comps Size: 2000 - With: 0.0048s, 22672 comps | Without: 0.0042s, 37745 comps Size: 5000 - With: 0.0110s, 63319 comps | Without: 0.0120s, 107652 comps Size: 10000 - With: 0.0206s, 136634 comps | Without: 0.0276s, 235294 comps Size: 20000 - With: 0.0454s, 293288 comps | Without: 0.0583s, 510657 comps Oh, there it is. 🙄
$ python bench.py With siftdown inlined: 3.995546 seconds, Comparisons: 1648612 Without siftdown: 3.329431 seconds, Comparisons: 1882563 🫣