Hacker News new | ask | show | jobs
by denster 2253 days ago
I'll give you an example that mid-way [1] disproves the above.

Think of a typical "product tour" in a SaaS product. We're building the MintData product tour, in MintData itself. We then "publish" this "product tour application", and include it with the original blank design that a user gets when they first enter MintData.

So, in a way, our MintData onboarding is built in/on MintData itself, a bit like how you can have a bootstrapping compiler (one that compiles itself).

So, is the above us "modifying the original system"?

I think to some extent yes, although we have special spreadsheet functions that help jump the gap between Onboarding Application and Blank User Design (akin to the Postgres extensions [2] above).

So I think it is possible to build a system that allows you to then customize the system's own behavior (earlier versions of MintData could not build the onboarding experience, similarly to how the first compiler has to be built in a lower level language).

Genuinely curious -- derefr, do you agree or disagree with the above?

--

[1] Chief abstraction wrangler at https://mintdata.com, so YMMV on the above.

[2] As a person who was held at Grade-point and forced to write PostgreSQL C code to "modify the original [Postgres] system", I can only say it's an acquired taste :) Even Prof Franklin at UC Berkeley I think would back me up on this :D :D

3 comments

Seeing your product shilled so blatantly repeatedly as one goes down the comments in this thread is pretty off putting.
Ouch! That hurts!

My only response is this: https://youtu.be/Mm4epcGApnY?t=14

Bootstrapping means only one thing: The entirety of a system is implemented within itself. This feat is binary: Only 100% means anything.

Your example is also very clearly not related in any way to "modifying the original system". Instead, it just means that you yourself have used project A (MintData) as a customer to make a distinct project B (an onboarding system that happens to be for MintData itself).

Modification is not assembling provided building blocks. Rather, it is changing the building blocks themselves. Say, you provide a HTTP JSON API, and I want to add support for websockets. Maybe I want to add entirely new data ingress/egress facilities. Or perhaps add a JavaScript interpreter to the backend to allow for rules and cron jobs written in JavaScript.

In your case, I see an ERP system which can be configured by users to do various things. From the perspective of the user, the original system is immutable, and they are no more able to change your product as a user than they are able to change Squarespace, GitHub, or for that matter Netflix and Spotify.

If you have navigated PostgreSQL C, you must surely understand the difference between configuration and modification.

---

General marketing trick: Use the product name less. It makes it stand out more to put it in one, well-placed spot. Use it too much (like above), and it instead becomes noise.

I think I get what you're talking about. Some systems are designed in such a way where the "platform" is formed in two layers: a low level, which exposes a set of primitives; and then a set of abstracting core libraries, implemented in terms of those primitives. Users are expected, idiomatically, to create business logic by making calls into the core libraries; but they're also free to call on the low-level primitives directly. In such a system, the "userland" sits directly on the primitives, with the core libraries as a sibling.

This is the pattern adopted by some, but not all, "runtimes." For example, Erlang has the low-level BEAM VM, and then has the Erlang "kernel" implemented as BEAM bytecode, rather than as native emulator support code. For another example, MOOs (object-oriented MUDs, e.g. LambdaMOO) only had the barest object-graph infrastructure specified in native code; everything else about the foundations of a MOO was defined in terms of objects and classes held in the MOO's state database.

In such systems, you have a sort of "intermediate" level of access to the native API surface, greater than the kind you have from the userland of a traditional VM or OS kernel.

Still, this "intermediate" level of access still doesn't allow you to break through the abstraction layer that the low-level primitives are founded upon. If there are any "complex" primitives implemented entirely natively (e.g. Erlang's `term_to_binary` function), then you can't "break into" that primitive to extend it unless the native runtime has been extended with an explicit "upcall" hook back into the VM userland.