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

ex-insider here, actually Git is used internally as a database of sorts. And it makes sense for many other reasons not cited. You are guaranteed to be able to access the "database" in a decade or two if you need to restore stuff without having to worry about binary compatibility. For more complex data types you can actually use an Sqlite database you save in a git-note. But this is very much about a very specific use-case. And the last paragraph could have been written less salesy and more "don't try this at home, don't run with scissors kinda message".

So this is kinda the contrary to "use Postgres for everything" vibe. Consider using Git as an actual database if you were considering using Sqlite or simple text files, or consider actually wrapping those with Git because it will give you quite a bit of extra oomph with very little effort.

I personally used git as a database on a project where we had just 200 records. With infrequent changes. Some bulk updates. That needed, for weird reasons, to be synchronized every ~12 months, yeah, and some of the nodes were air-gapped. As far as I know, more than 15 years later this is still running with basically 0 maintenance (other than git being upgraded with OS updates).


Well funny story, some twenty something years ago I actually worked on an election cycle volunteer infra thing in France, and living in Paris which is department 75 and therefore 750xx the prefecture being 75000 I assumed it was neatly hierarchical 75004 won't be far away from 75003 (true)... The French thing being orderly and rational.

I didn't need much precision so truncating seemed an easy way to group stuff.

Oh the surprise. I never again made such assumptions, let's just say I should have gotten a clue from Corsica being 2A and 2B.


For those interested, the practice of debasement actually predates the middle ages by, a lot. By 301 inflation was so bad Diocletian had to put out a price fixing edict. It didn't work. It took Constantine's Solidus (basically solid gold coin - that will stay stable for almost a thousand years) to stabilize the currency. By the early fourth century the denarius that used to have 50% silver contained almost no silver at all (something like 1 to 5%).


Between the years 150 and 100 BC, the Seleucid tetradrachm went from 95% silver to 65%. As the name suggests, it continued to weigh four drachms.

Debasement occurs any time the government runs out of money and can force people to take the debased money. The previous ~150 years of the same government minted tetradrachms that were all silver, probably because their main use of the silver was paying foreign mercenaries.

> By the early fourth century the denarius that used to have 50% silver

This is already a heavily debased coin. Nobody starts by adulterating their coins down to 50% monetary content.

> It took Constantine's Solidus (basically solid gold coin - that will stay stable for almost a thousand years) to stabilize the currency.

This isn't plausible; gold coins barely transact (gold is too rare). Minting coins that nobody uses won't affect the currency that people do use.

Wikipedia notes that, on issuance, Constantine's solidus was worth 275,000 denarii. The denarius was debased, but it was also a coin that people carried around and used to buy things. Think about the number of transactions that might plausibly have involved one or more solidi. If we underestimate the 4th-century denarius as being roughly as valuable as a US penny... how much use would you have for a $2,750 coin?


> This isn't plausible

Why? Of course it wasn't accessible or particularly useful for the majority of people but it was central to the Byzantine economy/financial-system functioned. Soldiers were paid in gold (every 6 or 12 months so that simplified things) and taxes were also collected in gold whenever feasible.

Relying on gold as your primary currnecy of course wasn't ideal since the outcome was a partially demonetisation of the wider economy.

However while it was was basically entirely unavailable in Western Europe and there were almost no gold coins in circulation until the 13th or so it was much more widespread in the Eastern Mediterranean.


> and taxes were also collected in gold whenever feasible

Well, for one thing, most people wouldn't be able to afford a single gold coin. You might collect taxes from a province in gold; you're not going to collect taxes from a person that way.

> the outcome was a partially demonetisation of the wider economy

This is also an odd claim; the number of denarii kept going up.

> it was central to [the way] the Byzantine economy/financial-system functioned.

Any time you have a system that doesn't involve something, that thing that isn't involved also isn't central to the functioning of the system. There is no way for such a rare coin to be central to the functioning of the system - if it disappeared entirely, the system would continue exactly as before, since almost nothing would have changed.


> the number of denarii kept going up.

It wasn't even minted by the 300s. There were multiple attempts to replace it with a new stable silver coin but none were very successful.

> Well, for one thing, most people wouldn't be able to afford a single gold coin. You might collect taxes from a province in gold; you're not going to collect taxes from a person that way.

Well yes, that was a significant problem. Often there was no other choice than to collect taxes in-kind and then the tax collectors either had to find local uses for all that stuff or sell it for gold that could be sent to the central treasury in Constantinople.

By the 500s the Empire was mainly only minting gold and bronze coinage which of course was very problematic (as you said gold is much too expensive for most transactions while bronze has the opposite problem). There were no stable, widespread silvers coins that were continuously minted until the 800s or so (Miliaresion) and then its value collapsed again after a few centuries when they went back to debasing during a period of economic crisis.

> There is no way for such a rare coin to be central to the functioning of the system

Well.. I accept that this is your opinion. Regardless, that's simply not how the Roman/Byzantine Empire worked. Gold coinage (or using gold solidus as the primary unit of accounting) was absolutely integral to its functioning. (moreover it was also central to international trade)


It was part of the downfall of the Roman Empire

1. Not enough mines to mine silver, exhausted based on their technology

2. China sold silk and other stuff and accumulating silver

https://cassandralegacy.blogspot.com/2014/03/peak-civilizati...


What's the downfall part of that?


If your money becomes worthless?


What does that have to do with downfall? The value of your money is whatever it is, determined by the productivity of your state and the amount of money it recognizes.

Given your username of "Beijinger", you should be familiar with the traditional Chinese currency: https://en.wikipedia.org/wiki/String_of_cash_coins_(currency...

> the weight of the Chinese money necessary for a journey of over three thousand miles was, as the Russian consul thought, one of the greatest of our almost insurmountable obstacles.

The extreme worthlessness of Chinese currency didn't play into any Chinese downfalls.

(Though it's not obvious to me why Sachtleben wanted to transport currency rather than bullion.)


The Roman Empire could not pay her troops anymore. Neither could they pay the Chinese for their products.

BTW, when China accumulated a majority of the world silver again and did not buy anything from the world, the British said, we have something you need! The reason for the opium wars....


Actually looks quite interesting. syntax looks like:

  fun
  | is_sorted([] || [_]): #true
  | is_sorted([head, next, tail, ...]):
     head .<= next && is_sorted([next, tail, ...])

  is_sorted([1, 2, 3, 4, 5])
  is_sorted([1, 2, 30, 4, 5])
a bunch of ways to express blocks, pattern matching and macros. The class facilities also look very nice. other than some indentation it doesn't feel pythony at all (which for me is a good thing!) more like an Elixir feel (cute syntax for some great concepts behind) see https://github.com/racket/rhombus/blob/master/demo.rhm


For a person that doesn't know racket, Haskell or any ML it looks unnecessarily convoluted.

My most charitable take is that it solves some problems I never seen a computer language have.


The above is a super concise syntax example that showcases multiple things at the same time. It is function definition mixed with pattern matching, with some advanced pattern matching features, like the '...' and '||' symbols. You can rewrite the example into the code below, if you find it to be more readable.

    fun is_sorted(list):
      match list:
      | []: #true
      | [_]: #true
      | [head, next, tail, ...]:
          head .<= next && is_sorted([next, tail, ...])
There's also a dot in `head .<= next`, because the syntax is sugar for `head.<=(next)`. Not sure why this is needed, but a quick read on the docs suggests this is done to enable static dispatch for some calls.


Not sure that can be called sugar when it it has just as many characters, two spaces rather than two brackets, with remaining lexies in same order, and the cognitive load is at least as important as it exposes the dot-notation within an infix three characters operator.

The global project might be nice, but in this particular case it's kind of opt for worst of all pre-existing conventions while trying to please everyone. The challenge is tough, so that's no wonder it will have hard time matching the goal.


It doesn't look terrible but colon after "match list" is optional.

And how would the last line look if the previous one didn't end in a colon?


Do you know why the tail is needed? Like, what would be the problem with this:

    fun is_sorted(list):
      match list:
      | []: #true
      | [_]: #true
      | [head, next, ...]:
          head .<= next && is_sorted([next, ...])


    ~ $ racket -I rhombus
    Welcome to Racket v8.13 [bc].
    > fun is_sorted(list):
        match list:
        | []: #true
        | [_]: #true
        | [head, next, ...]:
            head .<= next && is_sorted([next, ...])

    ; readline-input:6:19: next: cannot use repetition binding as an expression
    ;   in: next
    ; [,bt for context]

From there I got to "repetition binding" in the docs: https://plt.cs.northwestern.edu/pkg-build/doc/rhombus/Repeti...

From what I can understand, the "..." isn't independent of the previous expression in the list (as I would have expected from e.g. Prolog or Haskell). Instead you are defining a kind of pattern to reuse later, so tail gives a name to the rest of the list (so that it doesn't get associated with next).


Ah, now that makes sense, the three dots need to be assigned to a variable. It's just how they do it is completely new to me. Thank you for finding out!


I wondered this too, let's find out. I am looking all this up as I go, partially as an experiment to find out how easy it is to use Rhombus.

    $ raco pkg install rhombus --auto
which should work if you have some vaguely recent install of racket on your machine and handle the dependencies without prompting.

(I started installing this several hours ago on a slow machine but it's still going.)


It's supposed to take a couple of minutes.

Please file a bug report so this can be tracked down.

https://github.com/racket/rhombus


I'm not going to file a bug report, that's more time than I'm willing to spend on a project I'm not involved in. I will say I'm using Termux 0.118 and Racket 8.13 on kernel 5.10 and Android 14 and am willing to answer questions.


> I'm not going to file a bug report, that's more time than I'm willing to spend on a project I'm not involved in.

In that case, I make it quick - and refrain from any followup questions.

Did you by chance pick the "Minimal Racket" distribution?

If so, your command essentially compiled large parts of Racket and generated the entire set of documentation.

The distribution "Full Racket" is the recommended distribution for most purposes. It comes with everything pre-compiled.


No, but yes.

https://github.com/termux/termux-packages/blob/master/packag...

I just installed the package called `racket` from Termux's upstream, and it seems that they're using racket-minimal for that. Bit of a gotcha, but at least it doesn't seem like there's a bug. Thanks for the tip.


Thanks for the response.

I'll contact the Termux people and ask if the choice of `racket-minimal` was intentional.


As someone who has it doesn’t look convoluted and solves problems I’ve seen many computer languages have, especially non-functional-style ones.


What does | solve?

They are also using : ; , and a new line. Also ' and << >> that I have no idea how to type.

They are using both :~ and :: for type hints.

In none of the languages I've seen that was necessary or useful.

I think the problem they were solving was ... we really want to be able to cram everything into one line, so even if you split lines you might just as well still use the same characters despite them being unnecessary then.


The syntax `expr :~ annot` is used to annotate the expression with static information. This is different from type annotations.

It's a general mechanism to associate an expression with "extra information" that can be used elsewhere (at compile time).

One can for example using static information to implement dot notation for an object system. Using static information, one can push name resolution from runtime to compile time.

The important part is that users of Rhombus can use the mechanism for tracking static information specific for their programs.

It will be exciting to see the creative uses of this mechanism in the future.

https://docs.racket-lang.org/rhombus/static-info.html


> The syntax `expr :~ annot` is used to annotate the expression with static information.

Compiler can tell if a thing is static or dynamic and apply the correct behavior. Why would I ever want to check static thing only dynamically and why would I ever want to try statically check dynamic type if not by mistake?

If programmer doesn't really have a real choice why make him choose which buttons to press?


The idea behind macros is so to speak to allow the programmer to extend the compiler.

In a language like MetaPost I can use equations between variables:

   x + y = 10
   x - y =  6
A reference to a variable x will use the current set of equations and solve for x. The solution (it it exists) will become the value of the variable reference.

Let's say I want to extend Rhombus with this new kind of variable (let's call them linear variables).

Each linear variable needs to have some static information attached. Here the relevant information is the set of equations to consider. A reference to a linear variable will then reduce (at compile time) the equations associated with the variable. The reduced set of equations is then used to generate runtime code that finds the value.

In a sense "static information attached to an expression" is just a convenient way of working with compile time information (in the sense currently used by macros in Racket).


Is that the reason for two different type annotation signifiers? That some day I might want to extend the language with something?

It sounds a bit like if every C function (including hello world) had to have empty asm block because someone might need it some day.


The operator `expr :~ annot` simply attaches the static information to the expression.

The operator `expr :: annot` will at runtime insert a check that the expression satisfies the annotation.


What if I want both behaviors at the same time? Have some static information attached and also do a runtime check?


I'm a bit confused: Can this static information system be used for run-of-the-mill static type checking as well or not? And if so, does a static type checker for this language exist or is one in the works?


> Can this static information system be used for run-of-the-mill static type checking as well or not?

Yes.

As an example Matthew Flatt has implemented Shplait in Rhombus:

https://github.com/mflatt/shplait


Looks like Haskell.


Or like Standard ML.

But it's interesting, since I hadn't seen that part yet, only the loop part and some of the dynamic typing.

  for List:
    each i: [1, 2]
    each j: ["a", "b", "c"]
    [i, j]

  > [[1, "a"], [1, "b"], [1, "c"], [2, "a"], [2, "b"], [2, "c"]]

  for (i: 1..4):
    "number " +& i
    ~into List

  > ["number 1", "number 2", "number 3"]

  for:
    each:
      friend: ["Alice", "Bob", "Carol"]
      index: 1..4
    println(index +& ". " +& friend)
  1. Alice
  2. Bob
  3. Carol
It gave me the impression of more of a cross between Scheme and Python.


Yes, I also got Python vibes. That behind said, I'm digging infix less and less over time, and I'm actually starting to crave forth syntax, just got the complete lack of punctuation...

but, I actually really like what they have going here. Seems nice and minimalist, while meeting consistent and clean.


Oh. Actually got released today .. so we also did https://platform.sh/blog/bun-support-is-here/


Oh its a Friday. Deploying on Fridays is what we do. Here you go ... Bun 1.0 officially deployed on Platform.sh https://platform.sh/blog/bun-support-is-here/ enjoy.


Also. As I am excited. Here you go for a one-click deploy .. https://github.com/OriPekelman/express-bun/ Very unofficial. Very.


Slightly hijacking this thread to ask: I've not heard of Platform.sh before. Do y'all have a free/hobby plan for someone wanting to become familiar with the it? If not, no worries.


We are not big on free. We like money :) And people like that we will probably be around in a decade (and won't stop free as soon as we've locked enough people -in). We do have a no-strings-attached free trial ...


Well, it'a already been out for an hour ? Deploying on Fridays.


Composer is a simple but powerful CMS based on Pandoc, Bootstrap and GNU Make. From Gary of GaryOS. Gotta love the consistency. And gotta love the documentation of GaryOS.


Basically "Information theoretically" compression is a measure of informational distance. So basically if text A and Text B contactenated together, compress better than text A and text C it means A and B repeat more patterns. and are closer. All we need are some distance functions .. in a way you can think about it like Levenhstein distance but that can take into account inputs with very different sizes, repetitions, changes in order big inserts etc...

Reminds me of a mostly joke ruby project I did a decade ago https://github.com/oripekelman/simple_similarity


archive.org seems to side with the story telling of the Founder's counter-claim? January 2021 https://web.archive.org/web/20210128191225/https://withfrank... "We've helped over 350,000 people access financial aid resources" and https://web.archive.org/web/20210222193947/https://withfrank... February "4.25 Million students trust Frank." ... at any rate can't say the due diligence team did a brilliant job there... I mean they didn't bother to look at archive.org?


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

Search: