HN user

okennedy

393 karma

Hate notebooks... so do we. That's why we built one that doesn't suck. Check out Vizier, our spreadsheet-enabled, polyglot, notebook-flavored workflow system https://vizierdb.info

Posts7
Comments96
View on HN

Bash is ubiquitous and stable, making bash scripts incredibly portable.

All of the other languages you bring up are great for authoring code, but have a non-zero amount of friction when running code in the wild. Python may be omnipresent, but you can rarely count on a specific version or the presence of specific libraries. Go requires compiling platform-specific binaries. Even JVM- or JS-based software requires installing a separate toolchain first.

If you want to write some code (e.g., a launcher, installer, utility code, etc...) that is almost certainly going to run on any computing device created in the last several decades, bash is your language.

Automattic is a fantastic home for us. We needed a home (or new investors) to keep working on Beeper.

Is the added investment necessary to scale out specific features, or is it to address challenges related to profitability?

From a practical standpoint for most database systems, sort of? One might say that there's a functional dependency from the 'time' to the 'precipitation' attribute, and providing that information to the optimizer might affect its decisions... but at the level of data storage and query evaluation runtimes, there's not a huge difference.

From a data modeling and query optimization perspective, however, there's some value in distinguishing attributes uniquely related to identity (e.g., keys, or group-by attributes) and attributes that we're only interested in computing statistics over. This makes it easier to automatically create e.g., data cubes or similar indexes, and many useful statistics can be modeled using a nice mathematical structure like a ring or semiring [1], who's properties (commutativity, associativity, distributivity) are very helpful when optimizing queries.

Classical Datalog, in particular, is entirely based on the former type of attribute; value (dependent) attributes always need to be hacked in, in some way.

[1] https://dl.acm.org/doi/10.1145/1265530.1265535

The big difference I see at a skim is that, in classical datalog, facts are only allowed to contain domain attributes, and not value attributes. E.g., you can express binary facts like Raining(12:00) (it's raining at 12:00), but not Rain(12:00) = 5 in (At 12:00, 5 inches of rain had accumulated).

Value attributes make it much easier to express most forms of aggregation (sum, min, max), so you'll find very similar patterns in practical datalog variants e.g., RelationalAI's Rel [1], DBToaster's AGCA [2], etc...

Apart from that, and a syntax that seems to resemble map-style collection programming a bit more than datalog, yeah, this basically looks like datalog.

[1] https://docs.relational.ai/getting-started/rel/my-first-rel-... [2] https://dbtoaster.github.io/

TFA's point is that the model is horrible for creators: a revenue sharing model is only viable as long as the number of creators being shared is comparatively small. $5, $10, $20 from a few hundred or thousand viewers is a decent haul when compared to a few fractional pennies per view.

It makes sense that creators focus their efforts on cultivating personal relationships with a small, but loyal base. You're not their target demographic.

Differing skillsets? Managing people doesn't have to mean more responsibility. Some people are good at doing, others are good at the bureaucracy game and buffering for the doers. Both are critical, and in a good org, both have different, but not necessarily differing scales of responsibility.

NYC, and Manhattan specifically, is one of the rare places in the country where having a car is almost virtually unnecessary. In downtown, cars are already playthings of the rich: Just parking the car during peak hours can run you hundreds dollars of per month.

The core of NYC has walkable infrastructure and an amazing public transportation infrastructure (at least compared to much of the rest of the country). For those commuting in from suburbs, park-and-rides are already a far more cost-efficient option.

The researchers behind the project have since moved on, but the idea of a db underpinning a game engine came up over a decade ago in Walker White's work at Cornell. Unsurprisingly, there's a whole lot of ways in which expertise from the db community can be commoditized to allow game devs to focus on the game, rather than hand optimizing code. For example, query optimizers can make it easier to scale up complex agent behaviors [0]. The project also spawned some interesting work on checkpointing, distributed replication, and computation over uncertain state.

https://www.cs.cornell.edu/~wmwhite/papers/2007-SIGMOD-Games...

As the peer comment points out, functional data structures force you to be deliberate about where/when state changes take place. In particular, they force you to be cognizant of which version of a data structure a particular piece of code is referencing.

Immutable structures can help significantly in reducing race conditions in parallel code, as it is impossible for one thread to modify part of a data structure while another thread is accessing it. Each thread sees a consistent 'version' of the data structure until the code explicitly replaces it with a new version.

Immutability can also help with memory optimizations: A node of one data structure can be safely re-used in another data structure. For example, if you need to retain older versions of a tree, you can share common nodes (this is how GIT encodes version changes).

This is the canonical guide to reasoning about amortized runtimes. The exponentially growing ArrayBuffer (O(1) amortized append) is the classical data structure used to teach amortized runtimes, but the O(1) amortized functional queue Okasaki presents here gives a much better intuition for what amortized runtimes are all about.

Even open book exams can be gamed. There are whole industries set up around enabling in-exam communication (e.g. concealed subvocal mics/headphones) and outsourcing schoolwork.

It is definitely possible to design assessments on which cheating is difficult. For example, oral examinations or personalized per-student projects or exams. The problem is that this style of personalized assessment fundamentally does not scale past a few dozen students in a classroom.

You want a classroom that small, it's going to cost you. Just instructor salaries for would run each student 10-30k per year, and that's before paying for infrastructure (classrooms, tech, offices) and (admittedly not always useful) administration.

I'm not convinced that they need to. What threat model are you considering? In this case, the privilege that the user is granting the new hardware is the authority to unlock the phone.

Since the phone has to already be unlocked for this privilege to be granted, it can't be used to bypass authentication.

The hardware is already installed by this point, so if it's 'spying' it can do that. The user's choice has no impact on the hardware's ability to record and/or deliver information.

At best, the replacement hardware would be able to unlock the phone for the attacker at some later time. However, the cost of getting this customized unlocking device into the phone seems high given that the attacker needs physical access to the device to embed the hardware in the first place, and then again at a later time to get into the device.

There are simple ways to allow hardware changes without losing security. One straightforward idea: Once the phone is unlocked (e.g. by pin code) allow the user to authorize the new hardware.

This is effectively what Apple does already. The usual difficulties with asking users to make security choices don't really apply here: Physical changes to the hardware are requires, so security fatigue isn't as big a deal. Maybe you get some protection from wrench attacks by not having the authority to pair new internal hardware, but that seems like a very specialized use case...

From TFA:

- Users were notified that the posts were written in collaboration with a bot

- Human authors oversaw the posts, including having the ability to edit posts and having responsibility for hitting send.

The lack of informed consent from study participants would likely have killed this experiment in a normal IRB review, but they didn't just sic ChatGPT loose on people seeking psychological help.

Apple's Numbers has a relatively clever way to pull this off. If a cell (e.g., B:$2) is in a table with a column (or row) header, all formulas will use the header field value in the variable. e.g.,

  = floor( [Strength:$Value] / 2 - 5, 1)
These labels are purely descriptive. The underlying reference is still B:$2, but it makes formulas infinitely more readable without needing to manually define named ranges for everything.

(Among many other nice features Numbers has... one of the few things I miss since my switch to Linux)

Writing, especially when the intent is to transmit an idea, is a lot like writing code: (i) Make absolutely sure that you know what your goal is (and why it's your goal). (ii) Before you use a term or concept that the reader might not know, make sure you've defined it. (iii) Make sure to state your assumptions.

Like programming, start with the main argument (API) and then work your way backwards: What doesn't the reader know or agree with? What fact/claim would convince them? Why should they believe it? Repeat recursively as needed.

Finally, I have a list of 'weasel words': "this", "that", "it", "these", "them". Words like 'these' are referential, and it's really easy to use 'them' without actually referencing anything (uninitialized pointers?). If you see 'this' in your writing, force yourself to replace 'it' with few words summarizing the referential target.

Good low/no-code solutions do a great job of aiding discoverability and cutting the need to grapple with a language's syntax. Unfortunately, while this is a roadblock for many, the challenge is more fundamental. What makes a good programmer isn't knowledge of a language, it's the ability to translate a vague description of objectives into a precise specification of a solution (especially when the vague description is under-specified).

This is one of the biggest challenges I see people struggling with as they learn programming: Cutting out the implicit assumptions that humans make every time they communicate with each other, and interactively working to understand *exactly* what needs to happen and why.

Interactive AIs (e.g., Copilot, ChatGPT), in principle, could address the specification problem. Unfortunately, in their current state, they have no concept of what they don't know or understand. Gaps in the specification are filled in with assumptions, and one of the main criticisms of these tools at the moment is that they have no way to reason about how appropriate these assumptions are. It seems likely that we'll eventually reach a point where simple AIs can replace devs for the relatively simple tasks that low/no-code solutions target. However, for this to happen, (i) the AI would need the ability to reason about uncertainty/incompleteness in the prompt it's given, and (ii) the AI would need to be able to interactively work with the user to refine the specification.

There's a crucial distinction between being impressive and being useful. Is it impressive that we've gotten to this point? Certainly! Is this a tool that people can safely rely on? Probably not.

I can't emphasize this point enough. Hypercard was an amazing tool, in the same class of evolutionary steps forward as the spreadsheet. It's unfortunate that nothing's come along to replace it. (I still have fond memories of Hypercard class in high school)

Relatedly, although it still exists, Apple Numbers is one of the few pieces of software that I really miss since my move to Linux. It has lots of subtle design choices that gently nudge you towards good data organization habits (e.g., If you keep an index column and title row for each dataset, you get rewarded with readable cell references).

Even if this were the situation, and the owner of the 2nd repository were the one at fault, CoPilot can't point to the specific repository it "learned" the code from to absolve itself. If a human said, of sufficiently complex and virtually identical code, that they had made it independently, they'd be laughed out of a courtroom. In situations like this, the provenance of a generated idea (explainability) is needed to preserve trust.

Guardrails for stats are something that I've put a lot of thought towards. The fundamental challenge is that statistics is operating in a world of incomplete information. Statistical measures are almost never monotone with respect to new information, and so any new piece of context might completely invalidate an analysis. Going beyond the abstract requires an intimate knowledge of the domain being analyzed, and the limitations of statistical methods as applied to that domain. "Guardrails for stats" have to be domain- and even dataset-specific.

That's a fair long term view, and a sense for this type of nuanced choice is one of the marks of a good programmer. Not all students have the experience to judge the tradeoff, and so my goal as an educator is to default them to the safer of the two options. In this example, it's usually trivial to just add the static keyword to an already pure method. In my experience it's considerably harder to refactor a series of stateful methods that were incorrectly declared static, since you usually also have to plumb the state object through all of the callers, and their callers, and their callers, etc...