Interview with Gavin Howard

Entrevista com Gavin Howard - O autor da linguagem bc do toybox

    Recently  I posted on my blog the release of bc 5.0 developed by Gavin Howard. I've been following Gavin's bc since November 2018 when it was anounced that he was developing it as a patch to toybox. I also posted on my Instagram that I was testing Gavin's bc even it was under peding version on toybox directory and since then good things have happened. One of them is that I met Gavin  Howard who gaves this awesome interview. I Hope you guys enjoy it :)

Gabriel: First of all I would like to thank you for accepting my invitation for an interview.

Gavin: Thank you for asking! Most people don't care about bc, so it's nice that someone cares for once. :)

Gabriel: Could you tell us a little bit about yourself? (Personal and professional life)

Gavin: I graduated from university a few years ago with a degree in computer science. Since then, I have worked on personal projects while struggling to get, and failing to keep, a job. My wife is the breadwinner. I'm pretty sure I fail to keep jobs because of a lack of social skills, so I would suggest to your audience that they develop those skills early, even if it's hard.

    Since losing my previous job, I have been working on bc and other software, but I'll talk more about that software later.

Gabriel: Why did you decide to develop bc?

Gavin: It just happened, really. I was unemployed, and someone asked me to build a parser for bc because he wanted to do the math library. I decided to do it for the resume experience.

    Well, once I got the parser built, he still wasn't done, so I decided to take the plunge and write the math myself. At that point, I had a fully working bc. Took me about a month.

    And then I have been perfecting it ever since. It's been about 3.5 years since I finished the original implementation.

Gabriel: What are the main differences between GNU bc and your bc?

Gavin: You mentioned that my bc does not have some bugs that GNU bc has. I would like to explain that.

    bc is a program that is standardized by POSIX. POSIX is a set of standards for operating systems that most follow, including Linux and Mac OSX (to some extent). POSIX doesn't just have standards for the operating system, though; some standards are for tools that the OS should have bundled with it. Among these are the `ls` command, the `mkdir` command, the `ln` command, and the `bc` command.

    The bc standard defines what bc is supposed to do and how it is supposed to behave. If you write your bc scripts to follow that standard exactly, you can pretty well count on your script running the same on any bc.

    The bugs in the GNU bc usually have to do with deviations from the bc standard. My bc does not deviate from the standard at all, except for extensions which can be disabled.

    Beyond that, my bc has *so* many more extensions than GNU bc, which yes, does have some extensions. The extensions that my bc has and GNU does not include:
  1. A seeded pseudo-random number generator that will generate numbers of arbitrary size. This allows users to generate pseudo-random numbers in Bash scripts.
  2. A way to input and output numbers in scientific and engineering notations.
  3. Assigning strings to variables, passing them to functions, and returning them from functions.
  4. Some extra builtin functions (abs(), modexp(), divmod(), asciify(), etc).
  5. Some extra operators for truncation, extension, and decimal (not bitwise) shifting.
  6. An extended math library with a lot (94, I think?) of extra useful math functions. (One function is not really useful except for the library itself.)
  7. A command-line flag to make it easier to handle globals (ibase, obase, and scale).
Gabriel: In a particular conversation, you told me your bc was adopted by the toybox team to help toybox to build the Linux kernel. Can you give us more details about it?

Gavin: In the Linux kernel, there is a header that needs to be generated during the build. This header (include/generated/timeconst.h, see https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/Kbuild#L16) has the constants for how many milliseconds the kernel should wait before interrupting a process. Basically, this header defines the size of time slices (https://en.wikipedia.org/wiki/Preemption_(computing)#Time_slice).

    In order to generate this header, the kernel has an option (CONFIG_HZ, found under "Processor type and features" -> "Timer Frequency") that sets the number of times per second that the kernel should preempt processes. This frequency needs to be converted into the number of milliseconds per slice. Originally, the script to do this was in bc. It was changed to Perl because of GNU bc bugs, but switched back after those bugs could be worked around or fixed. (See https://github.com/torvalds/linux/commit/70730bca1331fc50c3caacaea00439de1325bd6e). The script is kernel/time/timeconst.bc (https://github.com/torvalds/linux/blob/5bfc75d92/kernel/time/timeconst.bc).

    The reason bc is used rather than Perl is because bc is a POSIX standard, so Linux can expect that it will exist on the system, whereas Perl needs to be explicitly installed. That said, the Linux timeconst.bc script uses some GNU extensions, which defeats the purpose.

    At the time, toybox had no bc, and so, by itself, was not enough to build the Linux kernel, and because the Linux timeconst.bc script used GNU extensions, it really needed the GNU bc. With the addition of my bc, which has all of the GNU bc extensions, toybox became able to build Linux without any other external utilities, a remarkable achievement for the toybox author.

bc code inside the Linux kernel
bc code inside the Linux kernel


Gabriel: In my personal opnion, bc is a good way to learn programming. Do you agree?

Gavin: I heavily disagree, actually. The reason is because there are numerous pitfalls and traps you can fall into when writing bc code. (See https://git.yzena.com/gavin/bc/src/branch/master/manuals/development.md#lib-bc-1). These snares include:
  1. There are three global variables (ibase, obase, and scale) that control how bc behaves. These globals must be handled properly at all times.
  2. The globals (ibase, obase, and scale) must be saved before being modified in a function, and must be restored before returning from a function.
  3. If constants are used, ibase must be explicitly set by the function (and restored before return) or else the constants will be interpreted in the wrong way.
  4. If the function prints a number to stdout, obase must be explicitly set by the function (and restored before return) before printing, or the number will be printed in an unexpected way.
  5. All variables local to the function must be in an auto statement at the beginning of the function, including arrays. If you don't do this, the variables or arrays are assumed to be global, and so the global versions will be used/changed. However, "global" in this sense is *also* misleading. Say you have a function that has the variable `a` as a local variable (it appears in the auto statement). If it calls a function that accesses a "global" `a`, the `a` that it accesses is not the true global `a`, but the version of `a` in the function that called it! This is in the standard, so I can't change it, but it is something to be aware of.
  6. The last snare is only for code that wants to be portable to any bc: you cannot use *any* extensions.
    That last one deserves a closer look. POSIX standard bc is bare bones; it has hardly anything at all! These are some of the things it does not have:
  1. Names longer than 1 character.
  2. `else` clauses for `if` statements.
  3. The `continue` keyword (though it does have `break`).
  4. An easy way of printing strings with escape characters (the `print` keyword in my bc).
  5. Return statements *without* parentheses.
  6. You can't use comparison operators outside `if` statements or loop conditions.
  7. You can only use *1* comparison operator per `if` statement and loop, so no `&&` or `||` operators!
  8. Technically, array parameters are somewhat limited as well.
  9. Strings can only be printed and nothing else done with or to them.
(For everything that my bc that POSIX standard bc does not, see https://git.yzena.com/gavin/bc/src/branch/master/src/data.c#L265-L283).

    That said, if you need to write a math script in a language with arbitrary-precision numbers, and Python won't work (Python has fairly good support for arbitrary-precision math), then bc might be what you need.

    Also, my bc removes a lot of those limitations. It removes number 2 (if you use the -g command-line option) and basically all of the limitations under number 6. The rest cannot be eliminated because they are inherent to the design of bc.

Gabriel: How can people contribute to your projects?

Gavin: I actually do not take contributions besides bug reports. My current project is at https://git.yzena.com/Yzena/Yc , and I explain my policy at https://git.yzena.com/Yzena/Yc#open-source-not-open-contribution.

    The part that is *not* written down is that, if I write everything myself, I can make sure that the software is of such high quality that I am willing to take liability for it. That's my current aim: to write useful software and accept liability for it, for a price. I figure that if I cannot get a job, I can make a job for myself by selling software and accepting liability for it.

 (But even if I sell software, it will still be open source! I will only sell liability protection, not the software itself.)

 That said, if you find a bug in bc and fix it, I'll still probably take your fix; I'm never going to accept liability for bc. You are also welcome to submit bug reports for *all* of my software.

Gabriel: Final consideration?

Gavin: I am currently writing a programming language, a build system, and a version control system. If any of your audience would like to contact me with comments or questions about those three things, or about my bc, they are welcome to. I'll try to respond as quickly as possible. To find my email address, go to https://gavinhoward.com/contact/.

Thank you for listening to me!

Comente com o Facebook:

2 comentários:

Viu algum erro e quer compartilhar seu conhecimento? então comente aí.

Observação: somente um membro deste blog pode postar um comentário.

Marcadores

A pior história sobre Linux que já ouvi (5) A.I (2) ambiente gráfico (19) AMD (14) analise (10) Andriod (16) android (7) Apple (1) arm (5) artigo (5) aws (1) bc (23) benchmark (6) BetrFS (1) blackhat (1) BSDs (30) btrfs (32) bugs (2) Caixa de Ferramentas do UNIX (19) canto do Diego Lins (2) certificações Linux (7) Código Fonte (54) comandos (31) comp (1) compressores (5) container (7) CPU (19) cracker (1) criptografia (5) crowdfunding (9) cursos (24) daemons (13) Debian (31) desempenho (1) desenvolvimento (90) desktop (19) DevOps (3) DevSecOps (4) dic (1) Dica de leitura (90) dica DLins (2) dicas do Flávio (27) Dicas TechWarn (1) diet libc (3) diocast (1) dioliunx (3) distribuições Linux (14) Docker (12) DragonflyBSD (22) driver (1) ead Diolinux (2) edição de vídeo (5) embarcados (1) EMMI Linux (4) emuladores (9) endless (5) English interview (3) Enless OS (2) entrevista (17) espaço aberto (82) evento (6) facebook (1) Fedora (10) filesystem (82) financiamento coletivo (2) fork (4) fox n forests (4) FreeBSD (20) Funtoo Linux (13) games (94) gerenciadores de pacotes (4) glaucus (3) GOG (3) google (9) gpu (3) hacker (2) hardware (104) hash (1) helenos (3) I.A (1) init system (11) Intel (15) inteligencia artificial (2) IoT (1) ispconfig (1) jogos (38) kde (1) kernel (138) lançamento (64) leis (1) LFCS (1) libs (2) licenças (8) Linus (16) linus torvalds (2) Linux (194) linux foundation (3) linux para leigos (1) live (5) LPI (8) LTS (1) Mac (1) machine learning (1) matemática (9) mesa redonda (27) microcontroladores (1) microsoft (6) microst (1) muito além do GNU (165) musl (3) não viva de boatos (9) navegadores (5) NetBSD (7) newlib (1) nim (1) nintendo (1) novatec (17) novidades (1) nuvem (1) o meu ambiente de trabalho (3) off-topic (12) open source (84) OpenBSD (7) OpenShift (1) oracle (1) os vários sabores de Linux (43) padrim (2) palestras e eventos (5) partições (6) pentest (8) performance (1) pipewire (1) plan9 (1) playstation (1) processadores (30) professor Augusto Manzano (11) Programação (64) promoção (1) propagandas com Linux (8) ps4 (1) real-time. (1) Red Hat (23) redes (4) resenha nerd (4) Resumo da Semana do Dlins (2) resumo do Tux (19) retrospectiva Linux (1) risc-V (14) RISCV (13) rtos (1) runlevel (2) rust (12) segurança digital (24) servidor web (2) servidores (2) shell (9) shell script (8) sistema operacional (25) skarnet (1) smartphones (3) Software livre e de código aberto (151) sorteio (3) Steam (10) Steam no Linux (8) supercomputadores (4) suse (6) systemd (7) terminal (89) terminal de comandos (18) toca do tux (1) toybox (27) tutorial (6) Tux (3) unboxing (7) UNIX (17) UNIX Toolbox (14) vartroy (1) vga (1) virtualização (2) vulnerabilidade (6) wayland (5) web (1) whatsapp (1) whitehat (1) Windows Subsystem for Linux (2) wine (14) WoT (1) yash (1) ZFS (15) zsh (3)