Hacker Newsnew | past | comments | ask | show | jobs | submit | mamcx's commentslogin

> Here’s my problem with reviving FoxPro in any form

And then it moves to the orthogonal problem:

> SQL DB

(that in fact means: An app made for end users that are not trusted by default but really are somehow that is a improper implementation of the relational model and more improper developer platform, more like wordpress, and because is mostly deployed "networked" suddenly need to worry about remote access, that is totally not the main point of old Fox/dbase apps!)

And the funny things: SQL injection is not a problem with a Fox app (use of a stringy api is a MAJOR issue that lack of a permission model)

---

As one that have long experience with FoxPro and try to revive the style, lets go to the core of the problem:

Imagine you say to a C developer:

"You can't use `fopen` and other filesystem APIs, because well you have access to to the whole filesystem"

Or even better, the user!:

"You should not own your own filesystem!"

The DB is like the filesystem, but not that dumb!

The permissions model is orthogonal. Maybe you (normal) filesystem is running on a networked deployment with access by spies with and other personal that should have top-notch security.

Or is just a embedded device.

WHAT DECIDE THE SECURITY MODEl?

The kind of storage?

Nope!

Is the deployment and use case.

Similarly, what decide the security of a database?, the fact is a "database"?

No!, that is ridiculous. If you need to layer some kind of access control or whatever, is outside of the kind of storage you choses.

In fact, see how Wonderfully could be all if the "filesystem" where an actual database and you can run relational queries on top: Millions of "cli utilities" suddenly are unnecessary, the user (and developers!) have more freedom and control, and your big corp with byzantine rules will be even more happy.

----

P.D: I'm very well aware of the limitations of Fox, is ancient software! but the style of programming? Is like have a taste of start trek

P.D.2: And note that the vector attack described here is a fault of the dumb filesystem, actually!


Remember when in movies getting access to this was THE THREAT?

Fun times.


The main kick is that there is not a way to "rewrite" a foxpro app without tons of stuff along the way!

(Example: You can ship an app that internally run `CREATE REPORT` and the report builder show up. You can invoke the debugger (that as I remember is the best I used a zero alternatives as good existed)) and so on


The runtime didn’t contain the debugger or other dev tools, only the dev version/IDE did. It did contain the report writer, though.

> Databases are a great piece of technology! Learning how to use them properly can have huge payoff in terms of business value generation.

Certainly.

Is a bit sad that the most well known are applications made for users (most RDBMS) instead of for developers, combined with a glorified DSL (SQL) that has never been made for make code at "large", not even at the scale of Lua or similar.

I worked with FoxPro and do all the DB code was not only a joy, it makes too much sense!

Thinking that interface with the network to store some meager byte on a disk is normal, that use terrible languages for data programming (not only SQL but JS, C# or whatever) is fine is baffling.

But well.

In terms of what is available:

* RDBMS despite being applications (including sqlite) and not developer frameworks are plenty flexible and powerful for at least solve most data-oriented coding

"DATA"-oriented is the key: Is wrong to say "this is backend, frontend, ui, etc" that is more a deployment issue and totally orthogonal.

The most obvious example is the effect of N+1 queries: You are not thinking in what is data-oriented and using a incorrect programming language to solve what even an anemic DSL like SQL do much better.

With the right mental model, is so easy to build a database schema with types, functions, procedures, views(that are so underused!) and such that make the clients DUMB.

IS MUCH EASIER!

And I work with ERPs, that are much more "complicated" than the median app.

Let the DB do what it does well and the rest will be simplified by leaps and bounds.

Even testing, just not commit the stupid mistake of use "mocks" that should be mocked and just spin ephemeral dbs/schemas. Is fast (even with PG) and will not create tons of churn because your regular langs is not ACID but the DB is.


Also reduce is a weird name.

Why? It does, after all, reduce a collection to a single value.

The resulting value can be anything you want. You can turn a list into a tree, or another list.

Bad example:

    reduce(lambda x,y: x+x.extend([y+2,y*2,y**2]), [1,2,3,4], [])
Reduces the list to another list three times as long.

It's a reduction in the sense of a transformation (also often seen in complexity theory), not in the "this makes this smaller" everyday usage that I think about first.


I suppose it's just so ... reductive, you know?

What about fold?

In rust iterators there's both fold (you supply the initial value) and reduce (it uses the first element as the initial value, doesn't work on empty iterators)

https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho...

https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho...


In the book "Simply Scheme", map is "every", filter is "keep", and reduce is "accumulate".

Senior Rust / Database Engineer

Also open to do custom software development!

Location: Medellín, Colombia Remote: Yes! Willing to relocate: No

Technologies: * System engineer: Rust · query engines · programming languages · VMs · transactions · storage · performance optimization · data modeling · ERPs · Business Apps

* Databases: RDBMs · PostgreSQL · SQL Server · SQLite · SpacetimeDB

* Backend: Business logic · APIs creation · integration · orchestration · ETLs

* Additional: Python, F#, Swift, Web assembly, Git, Jujutsu, macOS, Linux (NixOS, Debian), Windows

* ERP/eCommerce building from scratch

Résumé/CV: https://www.linkedin.com/in/mario-alejandro-montoya-cortés-6... Email: mamcx@elmalabarista.com https://www.elmalabarista.com

Software engineer with 30+ years building production-ready business applications and 3+ years as a core database engineer building high-performance RDBMs.

Founder and principal engineer of small ISV with a long track record of owning complex systems end-to-end, from low-level design to production reliability.

Driven to learn new domains quickly and choose the simplest effective architecture, tools and paradigms for each problem.


I also work on this area (https://tablam.org) and have used languages where this weird, poorly developed language SQL was not the main interface (FoxPro).

Think on this: You imagine yourself writing a regular website with ONLy sql? no, because SQL is not a "programming language" for developers.

Is possible you could think in various ideas about why is "nonsensical" to make an app with a relational language (that SQL clearly is not) but is the same as with OOP or functional: there is not reason to be a problem, and there is a lot of things that will be far easier if a proper relational language is used, like for example, is unnecessary and ORM and/or is not complicated and confusing to make one.


This make too much sense!

In special when testing against a DB.


It has good points, but has 2 major problems, IMHO, that we observed when I was part of a team building a RDBMS:

* It again ignore the best solution for nulls: Algebraic types. Once you have this much get solved for free

* The argument against bags:

The best idea of the paper is that a RDBMS in fact internally do different data structure and temporal representations that are not of concern to the user. Correct.

THEN it jumps to the conclusion that bags should not be presented to the user, despite the fact acknowledge it need to display them.

This is wrong, and the major reason that is always overlooked is that assume that 2 identical values are wrong to exist.

I can have "Jhon, Jhon", be 2 separate persons, not know at this time more to disambiguating, adding a Id do nothing to help me, and yet, this data is correct as is.

The language MUST allow me to deal with this. It will absurd to claim an array language, procedural, functional, imperative, declarative, etc can and a relational can't.

It say the lang is intentionally limited for purity, that true, is ideal in some cases, but that purity is what the engine/compiler should track, but not distort MY DATA for this.

And the part where the perf of having bags dismissed is easy to debunk: implement a dbms and profile.

P.D: Is true that set unlocks lots of benefits, and in some cases are ideal. But very fast once you hit the real world you see that need both, similar how btrees alone is not enough, and then there is hash-based indexes and many others.

it sucks, but reality is unfriendly to pure pure languages

P.D.2: And to clear misunderstanding, I agree with the points in the same way Rust say the borrow checker is ON by default, but I argue we CANT make a strict rule, in special because data is not ideological pure


this is an unfortunate take. btrees do not imply bags. in fact extreme bagginess can be a problem when all the keys in your page are the same. lets take this from the point of view of the user, we can certainly understand that some domain models really want to be set like, and other ones baggy.

if the base domain is sets we do get a lot of nice constraints, particularly with semantics around projections and if we want to support bags, its trivial to add a counter for the number of identical records as an additional column.

if we want to support sets in bag-land, we could imagine an extension which support 'row unique' on insertion. or we can use a 'unique results' post-filter. so there are paths, but its a lot less clear in a SQL context.

you insist that your data demands bags. I really prefer to work in sets and bagginess is always just a source of crappy errors for me. shouldn't we really support usable models for both regardless of the underlying storage?


> btrees do not imply bags.

Correct.

> you insist that your data demands bags.

No, I insist that real data needs both. You can bias the language/engine in one way or other.

The underlying problem is that once you say:

> if we want to support bags, its trivial to add a counter for the number of identical records as an additional column.

Then it means that this is second-class.

The main gripe I have, is that the relational model has this beautiful promise of "make the storage invisible" but need to have a coherent semantics about the data.

If you say "2 identical values/rows can't exist" then we adding the same problem that all the rdbms has: None implement the relational model, and none can deal with "relation on relations".

Imagine how crazy if I tell you a language can't do `[[1,2], [1, b10000]]` and to get into `b10000[:1] where ...` is necessary to switch to another paradigm.

P.D: note how "2 identical values can't exist" break when you have 2 columns, of numerical values, where the slice of both are the same value pair-wise: Are the 2 columns wrong?. And if both are called the same? same type? from different or same table? etc. "Duplicated" values are everywhere and is trivial to get there.

And if you "add a column" then it breaks the soundness of the language:

    IN: [1, 1] != OUT: [1: 1, 2: 1]


P.D: By causality we have worked together? You can reach me at https://www.elmalabarista.com


It blows my mind that Algebraic types are only just breaking into the mainstream. Someone told me Rust invented them, which is funny because Rust wasn't around in 1961!


It blows my mind that most HN users are still impressed by algebraic types but haven't heard about set theoretic types.


They probably just don't know the name. STT is what TypeScript uses, and that's pretty well-known, though a lot of the STT power is considered "advanced typing."

I write a lot in other language that uses ADTs, and I really miss STTs for the ease by which I can construct a "Partial" data type with significantly less boilerplate.

Of course, it also enables laziness, as instead of considerig whether it's proper to have a specific Partial product type, I just create it and move on. Easier to break loosey-goosey on modeling the domain.


There is not much material I can find out, maybe only https://elixir-lang.org/blog/2023/09/20/strong-arrows-gradua... that is kind of practical?


The only good reason is that SQL is the only main interface for most of the main DBs.

There is NOT other *good reason*.

P.D: But, why? Well, at first SQL was truly small. Then the cost of "just adding" something look easier than redo another lang.

TODAY, SQL is insanely bad and complex.

To the point that you can, literally, learn Rust faster than SQL.

Seriously! look for example how many reserved words you need to be aware of:

https://en.wikipedia.org/wiki/List_of_SQL_reserved_words

P.D: I implement parts of the SQL support for a RDBMS. I think the teams expect >5 years to fully do it.

I bet is possible to implement Rust way faster than that (ie: I mean here for both: Parsing and correctly executing, not all optimization and other concerns)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: