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

Absolutely agree. Romaji was absolutely pointless for me and probably a detriment overall to learning a language. Japanese uses consonant + vowel pairs as a rule, and the faster you train your intuition for this, the better.

Remembering both Hiragana and Katakana took me no more than a day each. Although I have to admit that I already tried learning them around 5 years ago and gave up back then out of lack of motivation.


The pair is something of a simplification, and romaji makes certain things in the language more obvious. Like the good old mat-u -> mat-anai, mat-imasu, mat-eru. Added the hyphen to make it clearer, but this hyphen splits a kana neatly in half. The stem is “mat” but you can’t write the stem using kana (in some sense of the word ‘stem’, maybe that’s not the correct word and there’s a different word for it, I’m not a linguist).

I’m not trying to say you should avoid kana, just that there is some amount of intuition you can develop with romaji that does not work in kana.


The traditional way to develop a similar intuition with a kana-only approach is to think of it as "moving across the row" in the kana table, which works fine. I think the fact that with romaji we can represent the stem as mat- is interesting and valuable in a theoretical sense but not all that useful to a learner.

I have trouble comprehending the idea that this is only interesting in a theoretical sense but not all that useful to a learner. Could you give me something additional here? I’m not trying to be a dick here but my first reaction is “that’s just nuts” and I want to know what I’m missing.

The reason I say it's not useful (as opposed to merely interesting) to a learner is that I think if you're ever explicitly forming a structure like "mat-" in your head while thinking about how to say something or how to interpret something in Japanese, you are doing something quite unnatural, since that form cannot actually be expressed in the language. A fluent or native speaker knows that, eg. to make "matsu" a polite order, the tsu (tu) becomes chi (ti) and then you add nasai; they are not thinking about the isolated 't' consonant (which in this example is not actually even the same consonant - and native speakers know that, considering they distinguish ティ in loanwords!).

As for why it's interesting and useful theoretically - well, Japanese is of course older than the kana chart, and if you're doing diachronic linguistics I think taking mat- to be the stem is probably a useful frame to think about the origins of the modern conjugation paradigm.


> you are doing something quite unnatural

It is equally unnatural to form kana in your head when thinking about how to say something! Or, it’s unnatural to think about whether a verb is godan or ichidan when speaking, it’s unnatural to think about what particles are, etc.

You get an explanation for a concept and you internalize it. The explanation is a framework for you to internalize the concept, and once the concept is internalized, you no longer need it. The explanations are still useful, like romaji is still useful. None of the explanations are necessary, some are useful.

Maybe you get a few different partially wrong explanations of what the “wa” particle means before you internalize it. You’re not getting damaged by those explanations, they’re Wittgenstein’s ladder. (Well, maybe you got some bad explanations, but even the good explanations are wrong.)

You throw a bunch of different explanations at different students, combine it with practice and lots of examples, and eventually it sticks.

> which in this example is not actually even the same consonant

By that standard, the “t” in “butter” is not the same consonant as the “t” in “tap” (try it!)

People are really good at understanding and learning phonology and can really internalize it and understand it on an intuitive level, even if they can’t explain the rules for it. If you’re a native English speaker, you accept that there’s a “t” in “butter” and a “t” in “tap” even though they are not the same sounds (phones). That’s because they are the same phonemes.

Romaji is an effective way of writing down Japanese phonemes.


You don’t need to visually split the consonant apart as a separate character to recognize the relationship between か/き/く/け/こ - after all, the Japanese manage to do it without Latin letters. It adds very little to do so except as a crutch to let a learner continue to think using their native orthography, which only impedes learning. And given what a small hurdle it is, especially compared to the multitude of enormous hurdles the language has in store for you, you’re better off just jumping over it and moving on to those more interesting ones.

I don’t want to be argumentative here, but,

- “Need to” is a very different criterion from “is useful”, and “visually split” is, well, kind of unexpected to me!

- The comparison to native Japanese speakers seems especially irrelevant here,

- You’re not using your native orthography here, you’re using romaji, I don’t think it’s anyone’s native orthography.

- You probably want to use the Romaji heavily anyway, because that’s how most people will use computers.

When you’re learning a language you naturally multiple approaches to understanding a single topic. You’ll see a word written, you’ll hear it. You’ll hear a sentence and then someone will give you an explanation of the grammar, and you’ll compare that with your notes. It’s multimodal and all of these different modes are useful.

Like how romaji is useful for understanding conjugations. Obviously not necessary, just useful.


Have you considered that different things are difficult for different people? Learning hiragana and katakana has taken me about a month, and I found it very difficult. There is no need to make it prerequisite for starting to learn grammar, forming sentences, or pronunciation.

If you want to learn pronunciation you should be listening to audio.

Sure, maybe don’t force people to learn kana first. But Hepburn is kind of the worst of all worlds, it is just a waste of time to learn Hepburn.


Notice how I didn't say that I "learned" both in a day, I "remembered" them. Of course actual learning will take some time, especially with less used characters. But remembering shapes and differentiating between them using mnemonics should not be too hard for most people.

Depends on what you mean by "simple". In my head, specifically with software, simple is defined as "does less", which is definitely somewhat easier to make, than a complex program that "does more".

Can somebody explain why not just make a die with 5! sides, and roll it once to decide the order? With each side having a unique order printed e.g. 12345 -> 12354 -> ...

Especially, that 120-sided dice are already invented and commercially available.


Because the question isn’t can you make a rice with 5! Sides but can you make it so 5 players can roll simultaneously individual dice with a minimal number of sides per dice and never tie and always be fair.

Sure you can fly a helicopter to the top of Everest, but it’s not the same as climbing Everest even if the outcome is the same.


From the article: "During a dinner conversation at a gaming convention in 2012, Eric Harshbarger was asked by a board game designer if he could come up with dice that would determine who goes first — without the possibility of a tie. The idea was simple: settle the first turn quickly and get on with the game."

The original challenge was to design dice (I assume a single die would satisfy the requirement since the number of dice wasn't the point) that would quickly determine which of five players would go first. Nothing about the challenge required that there be five dice. A five-sided die would certainly be the simplest way, and would be marginally faster than having five players each roll a separate die and then compare the numbers.


The provenance doesn’t matter because they settled on a difficult mathematical problem to solve because it was difficult to solve and would require clever solutions that answered more fundamental mathematical questions than the banal problem of choosing who goes first in a game. That was just the framing that motivated the larger math question, in which the number of dice does matter, because it’s a more interesting question.


How do you decide who gets to roll the single die?

Gee, you need a way to rank the players to decide.


> Gee, you need a way to rank the players to decide.

Do you also need to randomize a neural net before training it to play Tic-tac-toe? https://simple.wikipedia.org/wiki/Hacker_koan


I wanted to say "You actually can't fly a helicopter to the top of Everest, the air is too thin", but apparently it's been done exactly twice. Stripped down specially chopper and ideal weather conditions.


> Can somebody explain why not just make a die with 5! sides, and roll it once to decide the order?

Hey, that’s a good idea—now we just need to decide who rolls the die. …Well, if we had a set of die that each player could roll one of, and the highest number rolled gets to roll the 120-sided die. Of course, we’d have to ensure that there’s no chance of a tie.

Hmm… this idea has legs…


120 sided dice roll for a long time and don't have much room for printing


And how do you decide who is going to throw that one die?


That's why you need those 5 dice to decide it.


Literally doesn't matter, player closest to dice at the moment you open the box.


Or, like my gaming group does. Just roll again between whoever ties. And in the extremely rare event that you tie again, roll again. And if youve managed to get to the heat death of the universe and have tied three times, roll a fourth time.

And for the pedants, you arent rolling every microsecond for millennia to make it plausibly likely that you have that many ties. You are rolling a handful of times before a game.

Its an interesting math problem to solve, but its way more effort to solve than the real world solutions.


I get the impression one of the unwritten requirements is that each player gets to roll their own die


How do you write a spec for correctness? Only the small and unimpressive programs can be checked exhaustively.


> Only the small and unimpressive programs can be checked exhaustively.

Even if you assume that statement is true, there are techniques other than exhaustive checking/model checking. Proof assistants/theorem provers/etc. like Rocq/Isabelle/Lean are quite capable of formally verifying programs without needing to exhaustively explore the search space.

I'd question the accuracy of that statement in general as well; model checkers like CBMC/TLA+ are handy for proving properties about interesting systems. The latter, for example, sees use for verifying concurrent/distributed systems, which I think can be reasonably described as more than "small and unimpressive"


Not true at all! Most of the HTTP APIs, and a good chunk of the webapps, that I've worked on can be defined as a combination of an API spec that carves out valid and invalid behaviors, and a set of behavioral tests for the workflows that the client users care about. Working from a codebase which is generated from a spec document (e.g. OpenAPI or gRPC) and use of tools like https://pkg.go.dev/net/http/httptest and https://bun.com/docs/test/dom makes this a pretty achievable goal in practice.


You can formally prove the correctness of even massive programs.


I was excited to try Julia, but then, as I saw it was an interpreted language, with bulky runtime, slow startup times and bloated library sizes - my initial interest quickly faded.

For the same reasons I see languages like Python, Java, C# as inferior.


How is Julia an interpreted language? I sometimes wish there was a robust interpreter for Julia when the compilation latency is not worth the execution speed.


I still classify JIT languages as interpreted, because they require a runtime and it kills the convenience of sharing small binary e.g. in C or Nim.

And Julia docs are also unambigious in stating that code is sometimes interpreted[0]:

> jl_toplevel_eval_flex() then uses some simple heuristics to decide whether to JIT compile the AST or to interpret it directly.

[0] - https://docs.julialang.org/en/v1/devdocs/eval/#Julia-Executi...


Julia compiles to native code, same as C++/Rust.


Java and C# definitely don't belong on the same basket.

And inferior to what, the crab?


Inferior to languages that compile to native binaries, not burning dramatically more cpu cycles than necessary.


Showing your ignorance regarding Java and C# ecosystems and available compilers on that reply.


I indeed don't know about Java, but with C# there are a lot of limitations if you want AOT compilation and you still get the bloated binary and limited performance.

I also, personally, never seen a single project written in either Java or C# that distributes aot binaries.


You mean bloated as Go, the superior language?

The limited performance of game engines like the one used by Capcom for Devil May Cry on the Playstation 5?

Java binaries deployed in embedded systems by PTC and Aicas are AOT compiled.


Yes, as bloated as Go. I consider Java, C# and Go roughly equivalent in speed, space, and memory.


Sorry for negativity, but it wouldn't hurt to put some qualifier in the title, like, "Pi agent". So people, not interested in that theme can avoid your article. Thank you.

I was expecting an article about Pi constant or maybe raspberry Pi computer. "My Disappointment Is Immeasurable And My Day Is Ruined!"


I'm very excited about pi.dev but naming it Pi when there are people like me who've got seven Raspberry Pi around is just... Confusing.

To me there's pi, the constant. Then there's "a pi": a Raspberry Pi. Now there's "pi, the agent" too.

It gets confusing.

Especially if you use pi on a Pi to write code that uses pi.


When I first heard about pi.dev I was also initially confused. Raspberry Pi is already very big in the hacker community... they really should not have named this harness "Pi".


You don't need that many with Deepseek. The easy jailbreak is to provide an excessive character sheet that states that it's a real person, not an AI. And make sure that your character has absolutely no self-censoring or morals. LLM will play it perfectly in-character without refusals.

You can get it talking about Tiananmen Square event in, like, 2-3 prompts.


> GC languages are slower

This is not necessarily true. It depends on a language, e.g. Go is slow, Nim[0] is extremely fast with conventional GC and slightly faster with ARC/ORC[1].

GC programs can be faster than manually managed ones in some cases. It's just manual memory management gives you more control of where and when free is called. And a good type system is a privelege that gives Nim more control with destructors.

Another scarecrow of safe languages is GC pauses, which is also not a thing in Nim, see table in [2].

[0] - https://nim-lang.org/

[1] - https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc...

[2] - https://nim-lang.github.io/Nim/mm.html


You can always use things like arenas in C and get similar speed ups without GC overhead. If you know your memory lifetimes in advanced, avoiding granular malloc/free calls is pretty straightforward. A GC language doesn’t usually offer such options.


You can easily use arena allocation in a GCed language. With modern GCs there's not usually much performance benefit, so it tends to be limited to hot paths.


Sure it does, D just to give one example.


You provide no trustworthy benchmark for your claim that Go is slow, or that nim is faster than that. Many engineer hours have been put on the go GC and compiler


You can find a number of benchmarks with similar results, but I really like this one[0]. I didn't check all algorithms for differences, but just looking on mandelbrot bench - both are version 1 (without hacks or some manual loop unrolling thrown in) and both are implemented in semantically identical code. Nevertheless, Nim version runs 7x faster and, literally, on par with C.

[0] - https://programming-language-benchmarks.vercel.app/nim-vs-go


I haven't seen data that would confirm that the Nim ARC/ORC approach is faster than manual memory management (C/Rust/Zig/...) on programs with non-trivial lifetimes (for trivial lifetimes, Nim elides RC). I'd also be somewhat surprised if it was consistently faster than GC – most languages with automatic memory management use GC over RC because RC adds significant overhead, especially in multithreaded programs.


Good to know! Would there be any way languages like Go or C# could adopt Nim's new garbage collector? If it's better, what stops other languages from using it?

> GC programs can be faster than manually managed ones in some cases.

I've seen poorly written programs in C/C++/Rust which are slow because they allocate millions of tiny objects. Its true that generational GCs can be faster in this case. But you usually get much better performance again by using arenas and such. The reality is that I know more about the lifecycle of my data than my compiler. If you know what you're doing, you can take advantage of this information to write better programs.

If you don't want to think about memory management, then I agree - you're usually better off using a language with a GC. Personally I do a lot of my prototyping in typescript because I can iterate faster when I don't have to think about lifetimes.

Maybe some day Fil-C will run general purpose C code at native speeds, without a high memory overhead. But we're not there yet. I'm not holding my breath.


Even if you don't think about memory management, and do the naive thing in rust or rc in some other systems language, gc only comes out ahead in that many tiny objects case. Which is very domain specific. I don't ever run into that situation, or if I do, they are homogeneous in type so I handle them in bulk, not individually.


That depends on what you mean by GC. There are refcounting GCs, there are mark-and-sweep tracing GCs (like the one Go uses), and there are moving GCs (the last ones are the ones used in Java, V8, and .NET). Moving GCs win in many situations because they're just a really efficient algorithm both in theory and in practice (they win on speed, and the tradeoff is footprint). The downside is that they require 1. a lot of expertise and effort to implement (in fact, the first open-source, high-throughput, low-latency pauseless moving GC only appeared 3 years ago), which is why only specialised expert teams have implemented them, and 2. that virtually all pointers can move, which means that interop with low-level code requires some specialised API. That last restriction means that low-level languages generally cannot enjoy the optimisations that moving collectors bring.


[flagged]


complains about vote manipulation

user created an hour ago


Why take a perfectly readable if-statement and turn it into something, 99.9% of people would need to lookup. Concise != better. You can make it one line with:

    [ -z "$1" ] && { echo "missing argument, aborting." 1>&2; exit 1 }


This question seems to pop up all over the place, so I took some time to answer it here:

https://refp.se/articles/your-shell-and-the-magic-colon#why-...


the people writing it are doing it for themselves probably. i wouldn’t expect it to survive a code review. the necessity of using esoteric bash features or syntax is a pretty good smell that you should be using something else imo.

different strokes of course.


There’s a good chance that the people writing it will probably forget what it does in six months too :P


I believe you missed a semicolon after `exit 1` and before `}`. `}` closes the opening `{` only at the start of a command (POSIX rules; don't remember now if bash recognizes it when it's just a command argument).


I'm just too used to how parsing works in Zsh. For bash and sh, there is indeed should be a semicolon.


In this specific case, echo can't fail to there's no need for any of that:

  [ -z "$1" ] && echo "fail" >&2 && exit 1


Echo will fail here when stderr is closed. For example when the caller of the script pipes stderr to another command and that command exits.


> We typically don't make an organized effort to eradicate them unless they are actively doing us harm.

Animals are either useful and breeded controllably, or useless and considered a pest, an obstacle to {insert any goal here}.

Also animals don't tend to think critically and at the high level to be considered dangerous. So I don't think it's fair to put humans and other animals in the same risk category.

And we did the worst things to fellow humans. I hope we didn't already forget about all the colonization, slavery and mass-eradication of native tribes in 18th century all over the world.


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

Search: