HNHacker News
TopNewBestAskShowJobs

gary17the

853 karma · joined April 15, 2019

submissionscomments
gary17the··on LibreLingo – FOSS Alternative to Duolingo
> This is a false dichotomy. Focusing on grammar is not the opposite.

I don't follow you. I did not claim that focusing on grammar was a literal opposite of anything. I claimed that in my case "repetitive learning by example" turned out to be less boring than "repetitive learning by memorizing grammar".

In order to translate a randomly generated (thus never seen before, non-memorized) sentence from one language to another you have to understand the grammar in order to create a valid combination of words for your translation.

gary17the··on LibreLingo – FOSS Alternative to Duolingo
> the same question kept coming

I was under the same impression, but later the problem disappeared. You have to give Duolingo a couple of months of learning effort first, so that Duolingo has a larger base of sentences that you should already understand.

gary17the··on LibreLingo – FOSS Alternative to Duolingo
> [learning by translation] [is] an utterly broken approach to learning languages

I speak one foreign language fluently, which I learned in a traditional classroom environment with a teacher, and recently started to learn another language with Duolingo. I actually find their "learning by translation" method possibly easier (and definitely less boring) than the traditional "keep learning all the different grammar combinations first" approach, usually featured in a classroom or in self-learning video courses.

The only feature missing from Duolingo is short grammar summaries before new grammar constructs are introduced for the first time, as Duolingo unit/section "guidebook" entries are way to short and thus useless. You have to ask an LLM for an explanation every time a particular sentence turns out to be different from what you would expect.

gary17the··on Ask HN: Do you feel burnout from being less hands on as you become more senior?
Possibly, but not necessarily. You burn out even harder if you do even more of the same kind of work that has burned you out already. The OP mentions: "if I have time, I might actually build something small", "I miss being a person who actually does stuff" and specifically "[directing] [is] work I don't want to do anymore". If, after work, you try doing completely different kind of work (within reason, of course), especially the kind that you've always liked, you might find some motivation and get reinvigorated. A hands-on side project might work the same way a work-unrelated hobby would.
gary17the··on Ask HN: Do you feel burnout from being less hands on as you become more senior?
> I don't have long work hours. I receive a good salary.

Perhaps consider creating your own product as a "micropreneur": a mobile app, a SaaS service, a social media website, etc. Evenings/weekends at first, using your salary money for dev outsourcing and marketing. This kind of endeavor will feel very personal in the context of "ownership" and very hands-on in every respect. Make sure to read a couple of Product-Market-Fit books first (e.g., "Start Small, Stay Small" by Rob Walling), if you are not already familiar with the subject of business development.

gary17the··on Rewriting Rust
I think it would be helpful to clearly distinguish between "good ideas" and "excellent ideas". It's relatively easy in the complex art of programming to come up with a dozen good ideas. It seems very hard in the complex art of programming to come up with even one truly excellent idea.
gary17the··on Rewriting Rust
No, Linus Torvalds doesn't work on the Rust compiler, but it is up to people like Linus to support or shoot down a particular PL for a particular use case. And here we arrive at the heart of our discussion: I am personally much more interested in being able to use Rust for Linux kernel development at the cost of any programming convenience, while you are more interested in being able to use cutting-edge PL features. It is probably simply not possible to have a PL that does everything for everyone.
gary17the··on Rewriting Rust
I think it would be helpful to clearly distinguish between PL simplification (e.g., "if let Some(x) = x, x == 42 {}") and convenience-driven PL expansion (e.g., "let @discardable lhs = rhs ?? 0;"). In case of the former, I'm with you. In case of the latter, I'm not. Rust likely isn't meant to be a tool that is easy to learn at all costs (since the borrow checker does exist, after all). Rust is, IMvHO, supposed to be like vi: hard to learn and easy to use :).
gary17the··on Rewriting Rust
Javascript has a quite different use-case audience than Rust. As an example, try to convince a guy like Linus Torvalds to officially support a particular PL for Linux kernel development, when his absolute priority (quite rightly so) is predicable, performant and portable code generation on the same level as raw C, with ease-of-use of a PL not being even a distant second, if considered at all. JavaScript does not really have to live up to those kinds of challenges.

The assumption that "[Rust] stagnation" is due to some kind of "Rust committee inefficiencies" might be incorrect.

gary17the··on Rewriting Rust
> The rust RFC process is a graveyard of good ideas.

I actually have quite an opposite view: I think the Rust core team is 100% correct to make it very hard to add new "features" to the PL, in order to prevent the "language surface" from being bloated, inconsistent and unpredictable.

I've seen this happen before: I started out as a Swift fan, even though I have been working with Objective-C++ for years, considered it an awesome powerhouse and I did not really need a new PL for anything in particular in the world of iOS development. With time, Swift's insistence on introducing tons of new language "features" such as multiple, redundant function names, e.g., "isMultiple(of:)", multiple rules for parsing curly braces at al. to make the SwiftUI declarative paradigm possible, multiple rules for reference and value types and mutability thereof, multiple shorthand notations such as argument names inside closures, etc. - all that made me just dump Swift altogether. I would have to focus on Swift development exclusively just to keep up, which I was not willing to do.

Good ideas are "dime a dozen". Please keep Rust as lean as possible.

gary17the··on Ask HN: Must-Read Books for Startups?
"If you like that, you're gonna love this." (Private Hudson in "Aliens", 1986) - Ash Maurya, "Running Lean: Iterate from Plan A to a Plan That Works". Try to get your hands on a preview of the upcoming 3rd edition (10 years newer than the 2nd edition).
gary17the··on Linux 6.10 Will Print the Number of Populated Memory Slots at Boot Time
I have been yearning for this feature unremittingly since 1992. Now the intolerable void inside me will finally have been filled.
gary17the··on Cubic millimetre of brain mapped at nanoscale resolution
Not if you want to actually execute the state of a human brain in a digital simulation to see how it works and whether it still displays certain abilities such as comprehension and consciousness. Otherwise a digital scan of a brain is just a glorified microscope.
gary17the··on Cubic millimetre of brain mapped at nanoscale resolution
> we may likely discover that a huge portion of [a human brain] is redundant

Unless one's understanding of algorithmic inner workings of a particular black box system is actually very good, it is likely not possible not only to discard any of its state, but even implement any kind of meaningful error detection if you do discard.

Given the sheer size and complexity of a human brain, I feel it is actually very unlikely that we will be able to understand its inner workings to such a significant degree anytime soon. I'm not optimistic, because so far we have no idea how even laughingly simple, in comparison, AI models work[0].

[0] "God Help Us, Let's Try To Understand AI Monosemanticity", https://www.astralcodexten.com/p/god-help-us-lets-try-to-und...

gary17the··on Cubic millimetre of brain mapped at nanoscale resolution
[AI] "Frontier [supercomputer]: the storage capacity is reported to be up to 700 petabytes (PB)" (0.0007 ZB).

[AI] "The installed base of global data storage capacity [is] expected to increase to around 16 zettabytes in 2025".

Thus, even the largest supercomputer on Earth cannot store more than 4 percent of state of a single human brain. Even all the servers on the entire Internet could store state of only 9 human brains.

Astonishing.

gary17the··on Unix
Lowest. Common. Denominator. Every sage switches Visual Studio Code to vi mode.
gary17the··on Dada, an experimental new programming language
The distinction between `Rc<T>` and `Arc<T>` exists in the Rust world only to allow the Rust compiler to actually REFUSE to even COMPILE a program that uses a non- thread-safe primitive such as a non-atomic (thus susceptible to thread race conditions) reference-counted smart pointer `Rc<T>` with thread-bound API such as `thread::spawn()`. (Think 1-AM-copy-and-paste from single-threaded codebase into multi-threaded codebase that crashes or leaks memory 3 days later.) Otherwise, `Rc<T>`[1] and `Arc<T>`[2] achieve the same goal. As a general rule, many Rust interfaces exist solely for the purpose of eliminating the possibility of particular mistakes; for example, `Mutex<T>` `lock()`[3] is an interesting one.

[1] https://doc.rust-lang.org/rust-by-example/std/rc.html

[2] https://doc.rust-lang.org/rust-by-example/std/arc.html

[3] https://doc.rust-lang.org/std/sync/struct.Mutex.html

gary17the··on Dada, an experimental new programming language
I don't think it's necessary to understand every single `Rc<T>` method[1] to use Rust smart pointers to learn Rust. Perhaps try a different learning resource such as "Rust By Example"[2], instead?

[1] https://doc.rust-lang.org/std/rc/struct.Rc.html

[2] https://doc.rust-lang.org/rust-by-example/std/rc.html

gary17the··on Dada, an experimental new programming language
An interesting point, but I would have to see some very serious performance benchmarks focused specifically on, say, RC Rust vs. GC Golang in order to entertain the notion that an RC PL might be slower than a GC PL. Swift isn't, AFAIK, a good yardstick of... anything in particular, really ;) J/K. Overall PL performance is not only dependent on its memory management, but also on the quality of its standard library and its larger ecosystem, etc.
gary17the··on Dada, an experimental new programming language
No, not really. Firstly, there is no significant "friction" to using Rust smart pointers and internal mutability primitives, as those constructs have been added to Rust for a reason: to solve certain borrow checker edge cases (e.g., multiply interconnected data structures), so they are treated by the Rust ecosystem as first-class citizens. Secondly, those constructs make a pretty good educational tool. By the time people get to know Rust well enough to use those constructs, they will inevitably realize that mastering the Rust borrow checker is just one book chapter away to go through out of passion or boredom.
gary17the··on Dada, an experimental new programming language
If you do not want to mess with Rust borrow checker, you do not really need a garbage collector: you can rely on Rust reference counting. Use 1.) Rust reference-counted smart pointers[1] for shareable immutable references and 2.) Rust internal mutability[2] for non-shareable mutable references checked at runtime instead of compile time. Effectively, you will be writing kind of verbose Golang with Rust's expressiveness.

[1] https://doc.rust-lang.org/book/ch15-04-rc.html

[2] https://doc.rust-lang.org/book/ch15-05-interior-mutability.h...

gary17the··on Ask HN: Are there any good reasons to use C++ over Rust for new projects today?
Consider cross-platform -ness. For example, if you make a new app with domain logic in C++, you can build it on iOS through Swift/Objective-C++ >> C++, or on Android through Java JNI >> C++, or on React Native through JavaScript Interface (JSI) >> C++, or on Linux through wxWidgets >> C++, or... etc.

Other than that, Rust is a great language with a great compiler eliminating whole categories of bugs possible with C++.

gary17the··on Meta's serverless platform processing trillions of function calls a day (2023)
I could be wrong, but from my experience, serverless has only one crucial advantage over serverful: the ability to instantly scale up on a moment's notice. You deploy some code to an established cloud provider, the cloud infrastructure replicates the code across hundreds of compute instances in a hundred geographical locations (possibly utilizing a cloud data store, synchronized internally across all the compute nodes used) and suddenly there is no longer a single performance-sensitive "failure point". Your product can get on the front page of HN and survive.

When it comes to serverful, you have to provision (or perhaps "over-provision") resources ahead of time. If you can estimate your CPU/memory/disk/network needs beforehand, you can just as well rent an appropriately powerful, "serverful" server to achieve your goal. If you assume (figure out) a particular desired number of API requests per second that you need to handle, analyze and benchmark a particular set of hardware resources that can likely handle such throughput and also calculate a per-request -based price of the same throughput with a serverless provider, you will probably find that serverless is at least twice as expensive as serverful.

gary17the··on Meta's serverless platform processing trillions of function calls a day (2023)
I think the nomenclature comes from the fact that "traditionally", before you can upload a piece of code somewhere and have it executed, you have to first setup a server, as in: an instance of a particular operating system (a physical server or a VPS), hence the name "server-ful". In the "server-less" paradigm, you upload directly to an abstract cloud and have cloud infrastructure execute your code. Moreover, uploading to "a server" implies using a fixed, pre-allocated set of CPU/memory/disk resources that cannot grow dynamically, while "server-less" implies using dynamic infrastructure that can scale CPU/memory/disk resources up and down as needed and/or clone executed code across multiple internal compute instances controlled by a load balancer and so on - the notion of "a server" becomes no longer relevant.
gary17the··on Ask HN: Learning new coding patterns – how to start?
I have to disagree with some of the other posters in this thread: I think the only way to learn to control growing complexity of a software project is to use software patterns extensively, disregarding any associated productivity costs.

Don't forget about the two broadest programming methodology alternatives: Object-Oriented Programming (OOP) and Functional Programming (FP). Each has its own set of design patterns: OOP has the "The Gang of Four" -style patterns, FP has function composition -style patterns.

It is my personal feeling that the programming world is possibly slowly moving away from OOP and gravitating towards FP (especially when it comes to UI programming), due to FP's focus on ease of code comprehension and testability.

In the OOP-centric world, Rust comes to mind as a modern programming language that encourages consistent use of assorted OOP and FP patterns. In the FP-centric world, Elm comes to mind as a practical and straightforward programming language that uses FP patterns to solve web UI development problems.

For a book on OOP, see: https://en.wikipedia.org/wiki/Design_Patterns

For OOP design patterns in Rust, see: https://rust-unofficial.github.io/patterns/

For a book on FP, see: https://www.manning.com/books/grokking-simplicity

For FP design patterns in Elm, see: https://elmprogramming.com

gary17the··on Why the case for Rust is not particularly compelling
The case for Rust is not only memory safety, but also unexpected state mutation safety, as well as multi-threaded programming safety, as well as async programming safety, as well as (partial) logic error safety (e.g., forgetting to release a lock for resource access) and so on. Anyone who's ever worked on a large codebase will agree without a second thought that finding a bug takes (at least) ten times more effort than writing code, wrestling even the strictest of compilers, so the case for Rust, effectively, is the philosophy of shifting as much responsibility on the compiler as possible and thus reducing the potential bug surface as much as possible. A human being is not capable of consistently avoiding all bugs that human beings realize can be made. A compiler, on the other hand, is capable of always eliminating all bugs that compilers realize can be made. The knowledge of such potential bugs is transferred from a community of experienced programmers to a compiler through an advanced type system for a programming language and a specialized structure of interfaces for a standard library.
gary17the··on Ask HN: Which programming language to learn in AI era?
Learn a strongly-typed programming language (so the compiler can guide you on how to fix your mistakes), preferably with garbage collection (so the compiler can take care of memory management for you), preferably one that supports modern language constructs (so you can later on switch from one programming language to another without a lot of re-learning). The obvious choices are Golang, Rust, Typescript, Swift. I would probably recommend Golang, since it's the simplest and can be applied to various problem domains: command-line utilities, web development, etc. All you need to get started is YouTube online tutorials.
gary17the··on A half-hour to learn Rust (2020)
> this is one of the main things Rust users don’t promote enough

This is probably because using internal mutability not to achieve a valid design goal (such as a controlled side-effect on an otherwise immutable entity), but to side-step the borrow checker for ease of programming, is not considered idiomatic Rust and even though it makes a good educational tool, it should rather not end up in production codebases.

Firstly, when using regular references, you cannot create multiple mutable references. This rule prevents subtle bugs such as data races. When using internal mutability, you still keep that protection, but it is (undesirably) delayed from compile time to runtime, potentially causing an unavoidable crash/panic.

Secondly, when using regular references, you cannot create even a single mutable reference when an immutable reference already exists. This rule prevents subtle bugs such as unexpected mutation ("from under you") of data that was passed-in as immutable. When using internal mutability, you throw away that protection, since multiple immutable reference owners can request a mutable reference (even if only one at a time).

  use std::rc::Rc;
  use std::cell::RefCell;
  
  let entity1 = Rc::new(RefCell::new(42));
  let /* immutable */ entity2 = entity1.clone();
    
  *entity1.borrow_mut() += 27;
  assert_ne!(*entity2.borrow_mut(), 42);
gary17the··on A half-hour to learn Rust (2020)
The Entity Component System (ECS) pattern seems to side-step the Rust borrow checker entirely in order to solve the following issues, all at the same time: 1.) allow a "parent" entity to have a reference to a "related" entity, 2.) allow such a reference to a "related" entity to be mutable, 3.) allow multiple "parent" entities to reference the same "related" entity, and 4.) allow the overall system to deallocate a "related" entity at any time without invalidating the state of all the observing "parent" entities.

I have never written a game before, so Catherine West[1] might have very good reasons for choosing ECS, but I... am not so crazy about it. ECS seems to replace Rust references (raw pointers) and/or Rust smart pointers with indexes into one, large "registry" (a container: e.g., a `Vec<T>`) of entities (e.g., `struct` instances). In other words, instead of allowing a Rust pointer (a managed memory address) to keep a piece of memory alive, ECS chooses to have a "registry" keep a piece of memory alive under a particular index, managing allocation and deallocation manually.

In a sense, ECS dumps Rust memory management in favor of... writing the good, ol', data-and-function -oriented C. Quite needlessly (?), since the same (?) can probably be accomplished with Rust reference counted pointers[2], weak pointers[3] and interior mutability[4].

----- CUT HERE -----

  use std::rc::{Rc, Weak};
  use std::cell::RefCell;
  
  type WeakMutEntity = Weak<RefCell<Entity>>;
  
  struct Entity {
    related: WeakMutEntity,
  }
  
  impl Entity {
    fn new(related: WeakMutEntity) -> Self {
      Self { related }
    }
  
    fn use_related(&mut self) {
      let Some(related) = self.related.upgrade() else { return; };
      related.borrow_mut().use_related();
    }
  }
  
  let entity1 = Rc::new(RefCell::new(
    Entity::new(/* null */ Weak::new())));
  
  let entity2 = Rc::new(RefCell::new(
    Entity::new(Rc::downgrade(&entity1))));
  
  entity2.borrow_mut().use_related();
  
----- CUT HERE -----

If the above does not get the job done, the solution shouldn't be to just abandon the Rust borrow checker; the solution should be to get the Rust Gods to optimize the available pointer types syntax-wise and/or performance-wise.

[1] https://www.youtube.com/watch?v=aKLntZcp27M

[2] https://doc.rust-lang.org/book/ch15-04-rc.html

[3] https://doc.rust-lang.org/book/ch15-06-reference-cycles.html

[4] https://doc.rust-lang.org/book/ch15-05-interior-mutability.h...

gary17the··on A half-hour to learn Rust (2020)
> Now can I have just a safe C without all the other stuff, pretty please? :)

Hmmmmm, if you are not being forced by others into any particular Rust feature set (standard) and you are not being forced into any preexisting Rust codebase, then perhaps just forget the entire standard library, traits, async, etc. and go Bare Metal Rust[1], using only the Rust language features that you need and interfacing with external C APIs through Foreign Function Interface[2].

[1] https://google.github.io/comprehensive-rust/bare-metal.html

[2] https://doc.rust-lang.org/nomicon/ffi.html

← PreviousPage 2 of 6Next →