HNHacker News
TopNewBestAskShowJobs

bobwaycott

3,464 karma · joined March 4, 2010

Principal Elixirist.

Software perfectionist.

Open to collaborating and technical co-founding if the idea is right.

Personal web: https://bobwaycott.com

Email: hn@ my personal web domain.

submissionscomments
bobwaycott··on OpenBSD/ARM64 on Hetzner Cloud
This is a stub article. The original source is https://www.cambus.net/openbsd-arm64-on-hetzner-cloud/
bobwaycott··on Emoji Generator with AI
I assumed it was an intentional “two thumbs up/down” that amusingly highlighted questionable AI hands at the same time. :)
bobwaycott··on Microsoft is discontinuing Visual Studio for Mac after major overhaul
This is about Visual Studio, not Visual Studio Code. Two different products.
bobwaycott··on Ask HN: Tell us about your project that's not done yet but you want feedback on
You could try to use an AI text-to-speech to get a different voice? I wouldn’t judge based on voice (or the lack of it), but I also understand hating the sound of your own voice when recorded. ;)

Maybe even just short gifs/videos that show features in action alongside where you currently have some images?

bobwaycott··on Ask HN: Tell us about your project that's not done yet but you want feedback on
This is really, really cool. Great landing page—solid design, effectively sells me on the features and benefits.

Would love to see it in action—either some video or a way to try it on a private repo. Even if I can’t actually submit a PR review. :)

bobwaycott··on Ask HN: I learned useless skill of prompt engineering, how relevant will it be?
I’m not sure how one measures being a good prompter, but taking a step back, you’ve exercised and honed the skill of using language with precision to communicate ideas, requirements, and expected outcomes effectively. You can explain your ideas in a way that primes outcomes to your expected goals. When you see the outcomes aren’t aligning, you can further refine with language to correct course and steer back toward your goal.

That is a great skill to have. It’s the kind of skill that saves entire teams of product, design, and engineering folks tons of time. It’s the kind of skill that helps communicate ideas, requirements, and expectations no matter what the problem space in ways that ensure everyone is aligned, understanding, and working together. The absence of this skill usually leads to confusion, wasted effort, frustration, dissatisfaction, and other negative outcomes.

Learning skills often has a compounding effect, as well. Even if a given skill isn’t forever usable in its original form, what you learn along the way continues to pay dividends.

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
The goalposts of this conversation seem to keep moving. It sounds like you don’t like some of Elixir’s choices. That’s fair.

I wasn’t hand waving, I was simply summarizing guards in general. We’ve both provided the same explanation regarding why some things can or cannot be guards —you’ve linked to Erlang’s discussion of guards; I’ve linked to Elixir’s. So we both understand guards and their limitations.

I’m not terribly interested in arguing about what should or shouldn’t be “guard-worthy”. The built-in guards don’t strike me as arbitrary choices, but as intentional choices as part of designing core language features—that’s all in Kernel, on which everything else depends.

The URI module, while a great part of the stdlib, is not core language guard material. I can say that in 7 years, I’ve never needed or wanted a built-in guard to check if a character was a reserved URI char—but I can believe some problem spaces might have use for enhanced guards. Why, I’ve written my own for having more readable and shorter guards for things like empty lists, maps, and more. The ability to compose those from core language guards and features is one of the many things that makes Elixir a great language for my use cases.

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
You are reading an incredible amount of hostility into my comments that is not there.

> Translation: the person asking needs to RTFM because they have a problem with something that is obvious or I don't understand and it doesn't matter which. This isn't being rude.

That’s an incredibly uncharitable translation and doesn’t accurately match my meaning or intent. At each point in this thread, other commenters and I have provided explanations and linked documentation. Each response has been of the form “sure thing / that’s true, but it’s not obvious to me”. Then a repetition of the core complaint. This has led to more attempts at explanation and linking documentation, just to get the same response. Saying RTFM is one thing, but it’s simply not rude to suggest reading docs would bring clarity (and suggesting reading docs would help is not the same as answering “RTFM”).

> Translation: the person asking is wasting time, being unhelpful and unproductive asking questions

Not at all. I haven’t once felt like the person asking was wasting time, being unhelpful, or being unproductive asking questions. My comment was simply saying that it is immensely more helpful and productive [to a person entering Elixir for the first time] to read Elixir docs and guides and, where accessible, the language/stdlib source (it’s all Elixir), because it pays serious and continuous dividends on the journey of mastering the language—compared to jumping in deep before you’ve built an intuitive understanding of how it works. It wasn’t a slight or an insult.

It was the same advice I received early in my career in a completely different language that has proven itself true with every language I’ve learned since.

> Translation: the person asking must not be doing their job because they don't understand things the way I do (I'm a software perfectionist, ofc)

Amusing weaponization of my HN profile, but your translation is still unfair. Complaining about memorizing a handful of guard functions felt to me like complaining about doing the job. I don’t expect anyone to understand things the way I do. Nor was I trying to backhandedly insult or taunt.

I spend nearly half my working hours each week reviewing thousands of lines of Elixir code from hundreds of engineers, pairing with 10s of them, helping people learn, explaining how things work, and learning new things myself alongside them every day. Every time anyone doesn’t understand something, it’s an opportunity for us to pair up, dig in, review docs, come up with new explanations, show off code to explain and cement concepts, etc. That’s not the same thing as complaining and labeling something as a language problem, have multiple people trying to help explain it, but keep saying “but it’s not obvious and doesn’t match my expectations, so that’s Language X’s fault.”

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
It is not a tool’s fault that, upon providing the relevant material that describes its usage and helps a user learn how to use it, the user ignores that and then blames the tool for not working how they want it to work.
bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
> Then explain to me, … why URI.char_reserved?/1 is not instead called URI.is_char_reserved/1 such that I can use it in a guard.

Because it is not meant to be a guard—it cannot further empower a function head and pattern match and be optimized and/or inlined by the compiler. Simple as that.

    Not all expressions are allowed in guard clauses, but only a handful of them. This is a deliberate choice. This way, Elixir (and Erlang) can make sure that nothing bad happens while executing guards and no mutations happen anywhere. It also allows the compiler to optimize the code related to guards efficiently.[0]
> There's nothing intuitive about memorizing dozens of built-in functions that are (for opaque reasons) different from all the other built-in functions.

I’m sorry, but I’m now struggling to believe you’re discussing this in good faith. Opaque reasons? I see none. It sounds like you either do not like or understand the reasons. It also sounds like you have an expectation that the existence of a boolean function means you can use it in a guard. But that’s your expectations not matching the language’s features and reasoning, neither of which are opaque. There’s nothing intuitive about memorizing dozens of functions? Assuming you’re a software engineer, that is your job. I probably have hundreds of functions memorized, across dozens of standard library modules, in multiple languages. Even if I don’t recall what specific options or arity a function has, I still have enough of it learned because that is my job. It’s what we get paid well to do.

[0]: https://hexdocs.pm/elixir/main/patterns-and-guards.html#guar...

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
If you’re having to do extra mental work to guess, it means you don’t have enough familiarity with the language, its type checks/guards, and the standard library. That’s not the language’s fault.

If you want to check the type of a thing, you always want the matching `is_<type>`. It can be used anywhere in your code, including guards. There’s no guesswork involved here. That is the consistent rule.

When you see a function with a `?`, look at the typespec and the function name—give it the argument(s) it expects and it will answer the question on the tin with a boolean. Again, there’s no guesswork. These functions can be used anywhere except guards—that is the consistent rule for boolean functions.

> Is the thing I want to test written as a macro or not?

I have never had to ask myself this question, and I struggle to parse it. Is the “thing” you want to test referring to the value or to the test you wish to perform on that value? Since you’re asking about macros, I’m assuming you mean the guard test. For that, just learn what guards are available[0] (you can also write your own :D ).

[0]: https://hexdocs.pm/elixir/1.15.4/Kernel.html#guards

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
I was not being rude.

What you say is not obvious is, to me, a result of not reading the docs, guides, and source code of the language and its standard library. I have seen this pattern repeatedly—those engineers who have learned the language find these things obvious. It’s not an insult, but a push to fill in those gaps. Elixir and Phoenix both have some of the best documentation you will find.

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
> Actually, if I'm not mistaken, keyword lists themselves are just lists with tuples of atom/value pairs.

You are correct. A keyword list is `[{atom, any}]`.

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
The larger problem is not reading the docs to understand and learn language conventions. If one reads the docs, it is immediately clear that the `is_` prefix denotes a function that returns a boolean and can be used in guards. The `?` form is for all other functions that return a boolean. Which means one will gain an intuitive sense of every function you see in the `is_` and `?` forms.

It’d be immensely more helpful and productive if coming into a language meant one would spend the time to read, learn, and understand that language’s conventions and standard library—and read the source code for it! It pays serious and continuous dividends, and is the fastest way to gain an intuitive sense for the language.

bobwaycott··on Thoughts on Elixir, Phoenix and LiveView after 18 months of commercial use
I find a lot of engineers I work with don’t understand on_mount. You shouldn’t have duplicate logic in on_mount—if you do, that code should be in a module. You only have the logic once, but you may call the function twice (though you don’t have to).

All your auth logic (and any other bits you need to set while starting up request state) should be a function in a module somewhere that returns expected values. Then, you just care to set these values to Conn and Socket assigns appropriately, keeping in mind that Conns and Sockets aren’t the same—when you have one, you don’t have the other. Thus, on_mount to the rescue:

1. Use Plug pipeline(s) to call your module function to compute and add bits to Conn.assigns (and you can add those values to the session to avoid computing again, if you’d like).

2. Use on_mount to assign_new:

2a. assign_new pulls from Conn.assigns by key for the dead render while you have a Conn.

2b. The fallback function gets that value again when you no longer have a Conn (recompute or pull from session if already there).

Your actual logic should only exist in one place. And there are easy strategies you can use to avoid expensive computations if necessary.

[Edit]: Not suggesting you don’t understand it, just to be clear. I’ve just experienced a lot of coworkers fighting against, abusing, and misunderstanding Conns, Sockets, and assigns.

bobwaycott··on Espresso coffee mitigates the aggregation of Alzheimer′s associated tau protein
If you’re relying on anything other than your own fingertips, it’s time for some grip exercises. Lovingly hand-crafting your beans to fine powder—this is the way.
bobwaycott··on How to add spaces to the dock on macOS
I’ll have to give this a try and see if it still works. Thanks!
bobwaycott··on How to add spaces to the dock on macOS
I use my keyboard.

Typically, I switch via Raycast (or a similar tool like Spotlight, Alfred, etc): ctrl+space, then I type the first letter or two of the app I want, then hit enter. Same thing for starting all apps.

If I know the app I’m switching to was the last active app, I’ll occasionally use cmd+tab. Once cmd+tab is visible, I’ll sometimes use my arrow keys to move between apps.

If I’m switching between active windows of the same app, cmd+`. This is handy for switching between browser windows that have sets of tabs based on what I’m working on, docs I’m referencing, things I’m reading, etc.

My terminal is bound to option+space, so it’s easy to switch to (and I start it with Raycast as explained above).

I also rely on Raycast for positioning all my windows to different sizes and quadrants of the screen with my keyboard. I used to use different apps for all these use cases, but Raycast handles them all and more—calculations, looking up words in the dictionary, etc.

bobwaycott··on How to add spaces to the dock on macOS
Interesting. I never use the dock, so the most frustrating thing to me is when it pops up under my cursor and gets in the way of a window. Hiding it is the first thing I do on every Mac. I wish there was a simple setting to disable it completely.
bobwaycott··on Elixir for Ruby developers: the three most important differences
I’ve always found dialyzer errors to be quite straightforward and easy to understand—the challenge is finding where a poor typespec originates in a codebase (or dependency) with poor typespecs.
bobwaycott··on Elixir for Ruby developers: the three most important differences
The type system has moved from the research phase to in development: https://elixir-lang.org/blog/2023/06/22/type-system-updates-...
bobwaycott··on Elixir for Ruby developers: the three most important differences
Use `dbg` for prying. You can also use `break!` in an `iex` session to manually set breakpoints without modifying your source. Additionally, you can use Erlang’s `:debugger`for visual debugging, and `:observer` for understanding the entire VM when prying is not enough.
bobwaycott··on Nvidia Started in a Denny’s. Now It’s Worth $1T
I’ve talked about many things in a Denny’s. ;)
bobwaycott··on Colorado repealed law limiting municipal internet
Haha. That doesn’t surprise me at all. There is simply no comparison. Hope CHA is treating you well beyond just the internet!
bobwaycott··on Colorado repealed law limiting municipal internet
I don’t brag on Chattanooga, TN often, but when I do, it’s always about the municipal symmetric gig fiber—CHA/EPB was the first to do it in the US, it’s always been cheap, it’s more reliable than anything else anywhere I’ve been, no data caps or throttling, held off a Comcast lawsuit trying to stop them (so Comcast went to the state to legislate away meaningful competition), and (afaik) there’s no spying on you.

I was lucky enough to build a bunch of the software used consumer-side to enable signing up for and managing fiber internet/tv/phone service, was brought in to establish and run their first internal software team, and built even more cool software to make tech support real-time, improve the lives of CSRs, and more. And they’re now getting into quantum computing. Truly a great group of people trying to take care of their city, and every time I run into anyone, I’m still impressed by what they’re doing.

bobwaycott··on Minetest: An open source voxel game engine
You’re welcome, and I hope you have a ton of fun!
bobwaycott··on Minetest: An open source voxel game engine
That’s incredibly kind of you, thank you. I think I am really the lucky one.
bobwaycott··on Minetest: An open source voxel game engine
He was around 11-12 at the time. He and his brother were huge Minecraft fans (they still play all these years later), and he wanted to learn how to change the game like mods did. I worried Java would be a bit much and might get in the way of him just trying some simple things out, and Lua seemed much simpler and approachable for me to help him with. He was also a big superhero fan, so his first 3 modifications were to give himself superpowers. We added the ability to fly like Superman, run fast like the Flash, and jump huge distances like the Hulk. His favorite moment was when he activated the speedforce() and hulk_jump() together and realized he didn’t even need to fly because the speed-running and massive jump moved him further across the map at a faster rate of speed than his superman() function did. :)
bobwaycott··on Minetest: An open source voxel game engine
Minetest was the vehicle through which I first introduced my youngest son to programming around 7-8 years ago (iirc). The way his eyes lit up when he wrote some code to change the game and then played it was just magic. He still—as a freshman CS student wrapping up his first year—fondly remembers those magical feelings today.
bobwaycott··on The Struggle to Make Lab-Grown Meat
Wow. That chicken may be one of the most horrifying illustrations I’ve seen in a while.
← PreviousPage 2 of 34Next →