3,700 karma · joined May 11, 2011
A webcam doesn't need the latest and greatest video hardware. Give it a camera module from a midrange 2017 smartphone and use the latest image processing tricks, and you'll blow almost any webcam on the market today.
status=progress is also quite handy. You can splice a "| dd status=progress |" in the middle of a pipeline to get a sense of what's happening.
If your expertise is in low-level browser performance but you lack deep knowledge of React/etc, your skills aren't of diminishing relevance, and probably won't be for a long time.
And while I can see how reasonable people can disagree about the virtues of Mac/Windows/KDE open/save dialogs, Gnome definitely has the worst. Personally my KDE experience is limited, but of the other three I prefer macOS by a wide margin.
- You're connected to a remote host and you don't want an unexpected network issue to kill your session
- You want to be able to periodically check on the status of something on a remote host but don't feel like keeping the connection open all the time
- You want to connect to the same session from different clients
- You may need to restart you graphical session and don't want that to kill your terminal session
A really simple way you could get this working is what abduco and detach do: the demon just blindly shuttles input and output between the client tty and the virtual tty that the interactive process is running in. However, when you reconnect to an existing session, you get no context, because the server doesn't know what it would need to tell the client for it to reassemble the tty state.
In order for that to be possible, the daemon would need to keep track of the terminal state internally. It's really annoying that that's necessary because now your actual terminal emulator isn't directly communicating with the process it's displaying, and you won't be able to access any features of your terminal that the daemon doesn't support.
But once you already have this background process that's keeping track of terminal state, you might as well build in other features that would require that, like window management, otherwise people who want those features will end up having yet another layer of terminal. If you don't want those features, you can pretend they're not there.
I'm definitely very keen to use Asahi once it's more stable and has support for more of the hardware though. For now I have an Arch Linux ARM VM that I keep running for some things (Haskell development on M1 is still a bit of a mess) and I can VNC into a Linux desktop over 2.5 gigabit LAN when I really yearn for my old workflows.
Unless you're going to use rlwrap /bin/dash as your default interactive shell (please don't) you need to know both your interactive shell and standard shell if you're going to write portable scripts.
I think it would be terrible to include in the language because of the inconsistencies, but it is possible to make the two examples you listed as typical cases of interface->interface coercion work with generic methods, ugly as it may be.
package p1
type S struct{}
func (S) Identity[T any](v T) T { return v }
package p2
type HasIdentity[T any] interface {
Identity(T) T
}
package p3
import "p2"
// Because parameter v might be (and in this case is) coerced into
// p2.HasIdentity[int], this function gets a type annotation in the compiler
// output indicating that callers should pass a p2.HasIdentity[int] interface
// reference for v if it exists, or nil if it doesn't, as an additional
// argument.
func CheckIdentity(v interface{}) {
if vi, ok := v.(p2.HasIdentity[int]); ok {
if got := vi.Identity(0); got != 0 {
panic(got)
}
}
}
package p4
import (
"p1"
"p3"
)
func CheckSIdentity() {
p3.CheckIdentity(p1.S{})
}So now the static expressivity of the type system is compromised in the name of runtime introspection. Reminiscent of how when Java added generics, runtime introspection ended up totally blind to them due to erasure.
This seems like the result of not taking care to account for the possible future addition of generics when originally designing the language — it was always well understood that they’d be a likely later addition to the language. The ability to check if a value satisfies an interface at runtime doesn’t seem all that critical, although I could be missing something, I’m not a regular user of the language.
The current state of desktop Linux is that there's a category of Linux software that is suitable for beginners, which is built atop the set of features that make Linux excellent for the people who put the amount of time into learning the operating system that is appropriate for learning a professional tool. But this category of software (the GNOME and KDE desktop environments and 3rd party software intended to run inside one or the other) doesn't do much to ease the process of learning the deeper, more compelling aspects of Linux. It provides you with an interface that's recognizable to Mac and Windows users, but doesn't provide nearly as much power, and then expects you to learn Linux in all its depth to make up for that difference in capabilities.
That makes Linux great for people who just need a web browser and maybe an email client, and it makes Linux great for people who have enough background technical knowledge to learn all its depth, but leaves it vastly inferior for everyone who needs more than a Chromebook but doesn't need a professional tool. If you fall into that category today and want to use Linux anyway, you need to learn its depths, and expect that until you do, it will be worse than the OS you're coming from.
If we want to improve the situation, we need either go all the way and make GNOME just as powerful as macOS (which is a fools errand), or make GNOME better integrated into what Linux is already great at and ease the transition.
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git hg
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:git*' formats "%{$fg[cyan]%}(%{$fg[green]%}%s %{$fg[blue]%}%r%{$fg[cyan]%}:%{$fg[green]%}%b%{$fg[yellow]%}%m%u%c%{$fg[cyan]%})%{$reset_color%} "
setopt prompt_subst
export PROMPT="%{$fg_bold[red]%}%n%{$reset_color$fg[white]%}@%{$fg_bold[green]%}%m%{$reset_color$fg[white]%}:%{$fg[cyan]%}%1~ \${vcs_info_msg_0_}%{$fg_bold[white]%}%(#.#.\$) %{$reset_color%}" bash
PASTE_HERE
exit
Works for everything unless the pasted commands set variables you want to use.The internal space that the module occupied was the only real disadvantage of the pop-up camera, restricting the space available for the battery. Although I didn't have any complaints about the battery life of this phone.
(loop [i 0]
(println (get my-vector i))
(recur (inc i)))
Assuming no part of my-vector is cached at first, the first iteration needs to make a full 16 round trips to main memory — quite bad. But on the next iteration, all of that is cached, and we don't hit main memory at all, and the same until i=16, which requires one round trip. Then when i=16², we need to hit main memory twice, etc.No doubt this is quite a bit worse than having everything nicely laid out sequentially in memory, but it's not as bad as you're describing.
Of course, all of that is not that material to begin with given that most elements will be pointers to begin with
I guess this is sort of true. If you're doing random lookups, then using a persistent vector instead of an array list mean 17 trips to main memory instead of just 1, so it's not totally inconsequential.
But I think (hope?) that modern JVMs can optimize collections of small immutable objects so that they're not represented as pointers to the heap. Surely ArrayList<Integer> x gets represented as int x[], and not int *x[], at least with the most optimizing JIT level.
But when you're indexing into the vector sequentially, the memory layout plays rather well with memory caching behavior, and most lookups are going to be in L1 cache, just like they would be in a conventional array.
So lookups are a bit more expensive, but not as much more expensive as one might imagine.