all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [BLOG] rust blog post
@ 2019-11-25 10:30 Efraim Flashner
  2019-11-26  9:58 ` Pierre Neidhardt
  0 siblings, 1 reply; 7+ messages in thread
From: Efraim Flashner @ 2019-11-25 10:30 UTC (permalink / raw)
  To: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 309 bytes --]

There's one or two FIXMEs and the like in the blog post but I figured
I'd send it off anyway.

-- 
Efraim Flashner   <efraim@flashner.co.il>   אפרים פלשנר
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #1.2: rust-in-guix --]
[-- Type: text/plain, Size: 8323 bytes --]

It's easy to think of Rust as a new programming language but it has already been around for five years.  Rust has made it past it's 1.0 release and the compiler is written in Rust. We even have mrustc to act as a secondary method to bootstrap new Rust releases without falling back to downloading precompiled tarballs. So how is the state of Rust in Guix today?
Truthfully, Rust in Guix could be better. The developer story for Rust is pretty straightforward: write your program, declare your dependencies in a Cargo.toml file, and ```cargo foo``` will figure out your dependency chain. ```cargo build``` will download any missing dependencies, even using a cache directory to reduce downloads, and compile the bits of the dependencies that are needed.
But what about for distro maintainers?
Obviously we can't download dependencies at build time, they need to be packaged ahead of time. So we package those dependencies. But wait, those dependencies have dependencies that are needed, and those ones too. It's dependencies all the way down, hidden in 5 years of iterative development that we're late to the party to, trying to capture snapshots in time where specific versions of libraries built using previous generations. All this all the way back to the beginning, whenever that is.
Obviously humans are prone to errors, so to work around this while packaging Rust crates Guix has effectively two importers for crates, one that will import a specific version and list it's dependencies, and one that can take a crate and recursively import all the packages that it depends on. Currently some work is needed to allow the recursive importer to interpret version numbers, but for now it works quite well.
Taking a break from Rust for a moment, let's look at some of the other languages that are packaged. Packages written in C/C++, processed with autotools or cmake or meson, are the easiest. Dependencies are declared, source code is provided, and there's a clear distinction between source code and compiled binary; source code is for hacking on, binaries are for executing. The closest to a middle ground are libraries which allow programs to use features from other programs. In order to use a package, all of its dependencies must be packaged and the libraries linked.
Taking a look at the other end we have Javascript. Javascript is source code, it's ready to be read and hacked on. Javascript is already ready to be run, therefor it must be a binary. Its... both? Javascript libraries leave distro maintainers in a difficult position. Building Javascript ends up in the same problem as we saw with Rust, recursive dependencies all the way down, iterative versions depending on previous ones, and a misty past from whence everything sprang forth, which must be recreated in order to bring us back to the present day. But there's more difficulty, often even after a 'build' phase has been run and tests have been run on Javascript we're left with unchanged code. Except now it's no longer source, it's a binary... or something. So just what did we build and test?
We can worry about Javascript another time, Rust has a clear boundary between source code and binaries.
So how about python? Python is a scripting language and can be run without being compiled, but it also can be compiled (pre-interpreted?) to bytecode and installed either locally or globally. That leaves us with source code which can double as a binary, and a bytecode which is clearly a binary. Given these two states, we declare the uncompiled version as source code, ignore that it can be run as a script except when testing the code, and we never return to second-guess ourselves.
How about Go? Go is another language that defies packaging efforts, primarily because build instructions often make use of the HEAD of other git branches, not tagged and released versions. That the names of the libraries are long and cumbersome is mostly a secondary issue. On the developer side a binary is a ```go build``` away. Go will download missing source and compile libraries as needed. On a packager side the libraries are carefully gathered one by one, precompiled, and placed carefully in a directory hierarchy for use in future builds. What could be a long build of a program is replaced by an intermediate series of packages where libraries are pre-compiled, and at each stage only the new code has to be compiled.
For all except the distro maintainer, the similarities are strong between Rust and Go. In both cases dependencies are downloaded as part of the build process, there's a cache for the downloaded sources and the compiled libraries, and build artifacts can be reused between different programs with overlapping dependencies. For the distro maintainer many of these similarities are thrown out. Dependencies are packaged ahead of time and previously packaged libraries is literally a cache. Libraries can be reused for other packages, yes, but for Rust they're not.
Why not? If they're already compiled why not reuse them?
Previously we've discussed source code and compiled binaries (or libraries), but in Rust there are two types of libraries. There are dynamic libraries, packaged as ```libfoo.so```, and there are Rust libraries, packaged as ```libfoo.rlib``` or ```libfoo-MAGICHASH.rlib```. When a Rust package declares a dependency on a Rust library, it doesn't declare a dependency on the whole library but rather just on the parts that it needs. This means that we can get away with packaging only a portion of the dependent library, or the library with only some of its features or its own dependencies. When compiling a final binary, a Rust binary doesn't link to an rlib, it takes just the part that it needs and incorporates it into the binary. As far as package maintainers are concerned, this isn't ideal but it is something we can live with, we already have this case with static libraries from other languages. If we were to compile the binary manually the command would be ```rustc --binary foo --extern bar=/path/to/libbar.rlib``` and we'd continue on. However, when bar depends on baz, the similar command, ```rust --library bar --extern baz=/path/to/libbaz.rlib``` _doesn't_ link libbaz to libbar. This leaves us in a pickle; we know which libraries we need but we're unable to compile them individually and build them up iteratively until we reach the binary endgoal.
One of our packaged Rust programs, rust-cbindgen, is used by Icecat. Rust-cbindgen declares 8 (TODO: check this number) dependencies. When run outside of the build environment ```cargo build``` downloads a total of 58 (TODO: check this number) packages, compiles them and produces a binary. Our recursive importer created more than 300 new packages before it was told to stop. Returning to our build process for rust libraries, since we couldn't link one rlib to another rlib, we opted to compile one rlib and then place its source in the build directory of the next one where it was recompiled. Baz would be built, then baz's source would be put in bar's vendor directory where baz and bar would be built. After this baz's and bar's sources would be put in foo's vendor directory, where all three would be compiled. This sounds like Go, except that we're throwing away all the results of our builds each time we start a new package.
Since we were just copying the sources from package to package, the simplest solution was to consider the Rust dependants as shared sources and not as shared libraries. Yes, the same source would be used between multiple programs, but each one package already only took the small portion of the shared source that it needed so there was no benefit to compiling the entire package ahead of time, especially with the mounting recursive dependencies, who's compiled libraries were being thrown away anyway.
Rust-cbindgen ships with a Cargo.toml listing 8 dependants. It also ships with a Cargo.lock, detailing the 8 dependencies and the bits of other libraries that are needed. By packing the sources of the 58 enumerated libraries and placing them in the vendor directory where the necessary parts could be compiled we ended at the same place we were headed anyway; only the sources were propagated from package build to package build, only the source was the relevant part, only the source is shared.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-25 10:30 [BLOG] rust blog post Efraim Flashner
@ 2019-11-26  9:58 ` Pierre Neidhardt
  2019-11-26 10:27   ` Efraim Flashner
  0 siblings, 1 reply; 7+ messages in thread
From: Pierre Neidhardt @ 2019-11-26  9:58 UTC (permalink / raw)
  To: Efraim Flashner, guix-devel

[-- Attachment #1: Type: text/plain, Size: 159 bytes --]

I think the attachment broke the formatting of the file (there is no
paragraph break).  Could you resend it?

-- 
Pierre Neidhardt
https://ambrevar.xyz/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-26  9:58 ` Pierre Neidhardt
@ 2019-11-26 10:27   ` Efraim Flashner
  2019-11-26 12:26     ` Bengt Richter
  0 siblings, 1 reply; 7+ messages in thread
From: Efraim Flashner @ 2019-11-26 10:27 UTC (permalink / raw)
  To: Pierre Neidhardt; +Cc: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 470 bytes --]

Hopefully this is better. I added a new line between each paragraph

On Tue, Nov 26, 2019 at 10:58:41AM +0100, Pierre Neidhardt wrote:
> I think the attachment broke the formatting of the file (there is no
> paragraph break).  Could you resend it?
> 

-- 
Efraim Flashner   <efraim@flashner.co.il>   אפרים פלשנר
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #1.2: rust-in-guix --]
[-- Type: text/plain, Size: 8353 bytes --]

It's easy to think of Rust as a new programming language but it has already been around for five years.  Rust has made it past it's 1.0 release and the compiler is written in Rust. We even have mrustc to act as a secondary method to bootstrap new Rust releases without falling back to downloading precompiled tarballs. So how is the state of Rust in Guix today?

Truthfully, Rust in Guix could be better. The developer story for Rust is pretty straightforward: write your program, declare your dependencies in a Cargo.toml file, and ```cargo foo``` will figure out your dependency chain. ```cargo build``` will download any missing dependencies, even using a cache directory to reduce downloads, and compile the bits of the dependencies that are needed.

But what about for distro maintainers?

Obviously we can't download dependencies at build time, they need to be packaged ahead of time. So we package those dependencies. But wait, those dependencies have dependencies that are needed, and those ones too. It's dependencies all the way down, hidden in 5 years of iterative development that we're late to the party to, trying to capture snapshots in time where specific versions of libraries built using previous generations. All this all the way back to the beginning, whenever that is.

Obviously humans are prone to errors, so to work around this while packaging Rust crates Guix has effectively two importers for crates, one that will import a specific version and list it's dependencies, and one that can take a crate and recursively import all the packages that it depends on. Currently some work is needed to allow the recursive importer to interpret version numbers, but for now it works quite well.

Taking a break from Rust for a moment, let's look at some of the other languages that are packaged. Packages written in C/C++, processed with autotools or cmake or meson, are the easiest. Dependencies are declared, source code is provided, and there's a clear distinction between source code and compiled binary; source code is for hacking on, binaries are for executing. The closest to a middle ground are libraries which allow programs to use features from other programs. In order to use a package, all of its dependencies must be packaged and the libraries linked.

Taking a look at the other end we have Javascript. Javascript is source code, it's ready to be read and hacked on. Javascript is already ready to be run, therefor it must be a binary. Its... both? Javascript libraries leave distro maintainers in a difficult position. Building Javascript ends up in the same problem as we saw with Rust, recursive dependencies all the way down, iterative versions depending on previous ones, and a misty past from whence everything sprang forth, which must be recreated in order to bring us back to the present day. But there's more difficulty, often even after a 'build' phase has been run and tests have been run on Javascript we're left with unchanged code. Except now it's no longer source, it's a binary... or something. So just what did we build and test?

We can worry about Javascript another time, Rust has a clear boundary between source code and binaries.

So how about python? Python is a scripting language and can be run without being compiled, but it also can be compiled (pre-interpreted?) to bytecode and installed either locally or globally. That leaves us with source code which can double as a binary, and a bytecode which is clearly a binary. Given these two states, we declare the uncompiled version as source code, ignore that it can be run as a script except when testing the code, and we never return to second-guess ourselves.

How about Go? Go is another language that defies packaging efforts, primarily because build instructions often make use of the HEAD of other git branches, not tagged and released versions. That the names of the libraries are long and cumbersome is mostly a secondary issue. On the developer side a binary is a ```go build``` away. Go will download missing source and compile libraries as needed. On a packager side the libraries are carefully gathered one by one, precompiled, and placed carefully in a directory hierarchy for use in future builds. What could be a long build of a program is replaced by an intermediate series of packages where libraries are pre-compiled, and at each stage only the new code has to be compiled.

For all except the distro maintainer, the similarities are strong between Rust and Go. In both cases dependencies are downloaded as part of the build process, there's a cache for the downloaded sources and the compiled libraries, and build artifacts can be reused between different programs with overlapping dependencies. For the distro maintainer many of these similarities are thrown out. Dependencies are packaged ahead of time and previously packaged libraries is literally a cache. Libraries can be reused for other packages, yes, but for Rust they're not.

Why not? If they're already compiled why not reuse them?

Previously we've discussed source code and compiled binaries (or libraries), but in Rust there are two types of libraries. There are dynamic libraries, packaged as ```libfoo.so```, and there are Rust libraries, packaged as ```libfoo.rlib``` or ```libfoo-MAGICHASH.rlib```. When a Rust package declares a dependency on a Rust library, it doesn't declare a dependency on the whole library but rather just on the parts that it needs. This means that we can get away with packaging only a portion of the dependent library, or the library with only some of its features or its own dependencies. When compiling a final binary, a Rust binary doesn't link to an rlib, it takes just the part that it needs and incorporates it into the binary. As far as package maintainers are concerned, this isn't ideal but it is something we can live with, we already have this case with static libraries from other languages. If we were to compile the binary manually the command would be ```rustc --binary foo --extern bar=/path/to/libbar.rlib``` and we'd continue on. However, when bar depends on baz, the similar command, ```rust --library bar --extern baz=/path/to/libbaz.rlib``` _doesn't_ link libbaz to libbar. This leaves us in a pickle; we know which libraries we need but we're unable to compile them individually and build them up iteratively until we reach the binary endgoal.

One of our packaged Rust programs, rust-cbindgen, is used by Icecat. Rust-cbindgen declares 8 (TODO: check this number) dependencies. When run outside of the build environment ```cargo build``` downloads a total of 58 (TODO: check this number) packages, compiles them and produces a binary. Our recursive importer created more than 300 new packages before it was told to stop. Returning to our build process for rust libraries, since we couldn't link one rlib to another rlib, we opted to compile one rlib and then place its source in the build directory of the next one where it was recompiled. Baz would be built, then baz's source would be put in bar's vendor directory where baz and bar would be built. After this baz's and bar's sources would be put in foo's vendor directory, where all three would be compiled. This sounds like Go, except that we're throwing away all the results of our builds each time we start a new package.

Since we were just copying the sources from package to package, the simplest solution was to consider the Rust dependants as shared sources and not as shared libraries. Yes, the same source would be used between multiple programs, but each one package already only took the small portion of the shared source that it needed so there was no benefit to compiling the entire package ahead of time, especially with the mounting recursive dependencies, who's compiled libraries were being thrown away anyway.

Rust-cbindgen ships with a Cargo.toml listing 8 dependants. It also ships with a Cargo.lock, detailing the 8 dependencies and the bits of other libraries that are needed. By packing the sources of the 58 enumerated libraries and placing them in the vendor directory where the necessary parts could be compiled we ended at the same place we were headed anyway; only the sources were propagated from package build to package build, only the source was the relevant part, only the source is shared.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-26 10:27   ` Efraim Flashner
@ 2019-11-26 12:26     ` Bengt Richter
  2019-11-26 13:01       ` Pierre Neidhardt
  0 siblings, 1 reply; 7+ messages in thread
From: Bengt Richter @ 2019-11-26 12:26 UTC (permalink / raw)
  To: Efraim Flashner; +Cc: guix-devel

Hi Guix,
In case someone likes a narrower style:

On +2019-11-26 12:27:37 +0200, Efraim Flashner wrote:
> Hopefully this is better. I added a new line between each paragraph
> 
> On Tue, Nov 26, 2019 at 10:58:41AM +0100, Pierre Neidhardt wrote:
> > I think the attachment broke the formatting of the file (there is no
> > paragraph break).  Could you resend it?
> > 
> 
> -- 
> Efraim Flashner   <efraim@flashner.co.il>   אפרים פלשנר
> GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
> Confidentiality cannot be guaranteed on emails sent or received unencrypted

    It's easy to think of Rust as a new programming language but
    it has already been around for five years. Rust has made  it
    past it's 1.0 release and  the compiler is written in  Rust.
    We even  have  mrustc  to  act  as  a  secondary  method  to
    bootstrap  new  Rust  releases   without  falling  back   to
    downloading precompiled  tarballs. So  how is  the state  of
    Rust in Guix today?

    Truthfully, Rust  in Guix  could  be better.  The  developer
    story  for  Rust  is  pretty  straightforward:  write   your
    program, declare your dependencies in a Cargo.toml file, and
    ```cargo foo```  will  figure  out  your  dependency  chain.
    ```cargo build```  will download  any missing  dependencies,
    even using  a  cache  directory  to  reduce  downloads,  and
    compile the bits of the dependencies that are needed.

    But what about for distro maintainers?

    Obviously we can't download dependencies at build time, they
    need to  be packaged  ahead  of time.  So we  package  those
    dependencies. But wait, those dependencies have dependencies
    that are needed, and those  ones too. It's dependencies  all
    the way down,  hidden in  5 years  of iterative  development
    that we're late to the party to, trying to capture snapshots
    in time  where specific  versions of  libraries built  using
    previous generations.  All  this all  the  way back  to  the
    beginning, whenever that is.

    Obviously humans are prone to errors, so to work around this
    while  packaging  Rust  crates  Guix  has  effectively   two
    importers for  crates,  one  that  will  import  a  specific
    version and list it's dependencies, and one that can take  a
    crate and  recursively  import  all  the  packages  that  it
    depends on.  Currently  some work  is  needed to  allow  the
    recursive importer to interpret version numbers, but for now
    it works quite well.

    Taking a break from Rust for a moment, let's look at some of
    the other languages that  are packaged. Packages written  in
    C/C++, processed with autotools or  cmake or meson, are  the
    easiest. Dependencies are declared, source code is provided,
    and there's  a clear  distinction  between source  code  and
    compiled binary; source code is for hacking on, binaries are
    for executing. The closest to a middle ground are  libraries
    which allow programs to use features from other programs. In
    order to  use a  package, all  of its  dependencies must  be
    packaged and the libraries linked.

    Taking  a  look  at  the  other  end  we  have   Javascript.
    Javascript is source code, it's ready to be read and  hacked
    on. Javascript is already ready to be run, therefor it  must
    be a binary. Its... both? Javascript libraries leave  distro
    maintainers in  a  difficult position.  Building  Javascript
    ends up in the same problem  as we saw with Rust,  recursive
    dependencies all the way down, iterative versions  depending
    on previous ones,  and a misty  past from whence  everything
    sprang forth, which must be  recreated in order to bring  us
    back to the present day. But there's more difficulty,  often
    even after a 'build' phase has been run and tests have  been
    run on Javascript we're left with unchanged code. Except now
    it's no longer  source, it's  a binary...  or something.  So
    just what did we build and test?

    We can worry about Javascript another time, Rust has a clear
    boundary between source code and binaries.

    So how about python? Python is a scripting language and  can
    be run without being compiled,  but it also can be  compiled
    (pre-interpreted?) to bytecode and installed either  locally
    or globally.  That  leaves us  with  source code  which  can
    double as  a  binary, and  a  bytecode which  is  clearly  a
    binary. Given these  two states, we  declare the  uncompiled
    version as  source code,  ignore that  it can  be run  as  a
    script except when testing the code, and we never return  to
    second-guess ourselves.

    How about Go? Go is  another language that defies  packaging
    efforts, primarily because build instructions often make use
    of the HEAD of other  git branches, not tagged and  released
    versions. That  the  names of  the  libraries are  long  and
    cumbersome is  mostly a  secondary issue.  On the  developer
    side a binary  is a  ```go build``` away.  Go will  download
    missing  source  and  compile  libraries  as  needed.  On  a
    packager side the  libraries are carefully  gathered one  by
    one,  precompiled,  and  placed  carefully  in  a  directory
    hierarchy for use  in future  builds. What could  be a  long
    build of a program is replaced by an intermediate series  of
    packages where libraries are pre-compiled, and at each stage
    only the new code has to be compiled.

    For all except the  distro maintainer, the similarities  are
    strong between Rust and Go.  In both cases dependencies  are
    downloaded as part of the build process, there's a cache for
    the downloaded sources and the compiled libraries, and build
    artifacts can  be  reused between  different  programs  with
    overlapping dependencies. For the distro maintainer many  of
    these similarities are thrown out. Dependencies are packaged
    ahead of time and previously packaged libraries is literally
    a cache. Libraries  can be reused  for other packages,  yes,
    but for Rust they're not.

    Why not? If they're already compiled why not reuse them?

    Previously we've discussed source code and compiled binaries
    (or  libraries),  but  in  Rust  there  are  two  types   of
    libraries.  There   are  dynamic   libraries,  packaged   as
    ```libfoo.so```, and there are  Rust libraries, packaged  as
    ```libfoo.rlib```  or  ```libfoo-MAGICHASH.rlib```.  When  a
    Rust package declares  a dependency  on a  Rust library,  it
    doesn't declare a dependency on the whole library but rather
    just on the parts that it needs. This means that we can  get
    away with packaging only a portion of the dependent library,
    or the library  with only some  of its features  or its  own
    dependencies. When compiling a  final binary, a Rust  binary
    doesn't link to  an rlib,  it takes  just the  part that  it
    needs and incorporates it into the binary. As far as package
    maintainers are  concerned,  this  isn't  ideal  but  it  is
    something we can live with,  we already have this case  with
    static libraries from other languages. If we were to compile
    the binary manually the  command would be ```rustc  --binary
    foo --extern bar=/path/to/libbar.rlib```  and we'd  continue
    on. However, when bar depends  on baz, the similar  command,
    ```rust --library  bar --extern  baz=/path/to/libbaz.rlib```
    _doesn't_ link libbaz to libbar. This leaves us in a pickle;
    we know which libraries we need but we're unable to  compile
    them individually  and build  them up  iteratively until  we
    reach the binary endgoal.

    One of our packaged Rust programs, rust-cbindgen, is used by
    Icecat. Rust-cbindgen declares 8  (TODO: check this  number)
    dependencies. When  run  outside of  the  build  environment
    ```cargo build``` downloads a total of 58 (TODO: check  this
    number) packages, compiles them  and produces a binary.  Our
    recursive importer created more than 300 new packages before
    it was told to stop. Returning to our build process for rust
    libraries, since we couldn't link one rlib to another  rlib,
    we opted to compile  one rlib and then  place its source  in
    the build directory of the next one where it was recompiled.
    Baz would be built, then baz's source would be put in  bar's
    vendor directory where  baz and  bar would  be built.  After
    this baz's and bar's  sources would be  put in foo's  vendor
    directory, where all  three would be  compiled. This  sounds
    like Go, except that we're throwing away all the results  of
    our builds each time we start a new package.

    Since we  were  just copying  the  sources from  package  to
    package, the  simplest solution  was  to consider  the  Rust
    dependants as shared  sources and not  as shared  libraries.
    Yes,  the  same  source  would  be  used  between   multiple
    programs, but each one package  already only took the  small
    portion of the shared source that it needed so there was  no
    benefit to  compiling  the  entire package  ahead  of  time,
    especially with the  mounting recursive dependencies,  who's
    compiled libraries were being thrown away anyway.

    Rust-cbindgen ships with a Cargo.toml listing 8  dependants.
    It  also   ships  with   a  Cargo.lock,   detailing  the   8
    dependencies and  the  bits  of  other  libraries  that  are
    needed.  By  packing  the  sources  of  the  58   enumerated
    libraries and placing them in the vendor directory where the
    necessary parts could be compiled we ended at the same place
    we were headed anyway; only the sources were propagated from
    package build  to package  build, only  the source  was  the
    relevant part, only the source is shared.

-- 
Regards,
Bengt Richter

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-26 12:26     ` Bengt Richter
@ 2019-11-26 13:01       ` Pierre Neidhardt
  2019-11-27  0:19         ` Bengt Richter
  0 siblings, 1 reply; 7+ messages in thread
From: Pierre Neidhardt @ 2019-11-26 13:01 UTC (permalink / raw)
  To: Bengt Richter, Efraim Flashner; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 523 bytes --]

Bengt Richter <bokr@bokr.com> writes:

>     be a binary. Its... both? Javascript libraries leave  distro

Typo: "It's".

Interesting read, thanks for sharing.
Do you intend to publish it on Guix' blog?  If so, I think the tone
might come across as a little bit too "rantish", maybe make it a little
more neutral / balanced.

I'd also elaborate the intro / conclusion to make the context a bit
clearer and maybe explain what you think should be done.

Cheers!

-- 
Pierre Neidhardt
https://ambrevar.xyz/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 487 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-26 13:01       ` Pierre Neidhardt
@ 2019-11-27  0:19         ` Bengt Richter
  2019-11-27  9:38           ` Efraim Flashner
  0 siblings, 1 reply; 7+ messages in thread
From: Bengt Richter @ 2019-11-27  0:19 UTC (permalink / raw)
  To: Pierre Neidhardt; +Cc: guix-devel

Hi Pierre, and apologies to Efraim...

On +2019-11-26 14:01:10 +0100, Pierre Neidhardt wrote:
> Bengt Richter <bokr@bokr.com> writes:
> 
> >     be a binary. Its... both? Javascript libraries leave  distro
> 
> Typo: "It's".
>

I noticed that too, but it's Efraim's typo,
as is the entire text: I merely reformatted Efraim's post
into a sort of rfc-style, i.e., Left-and-Right-justified.

So, credit to Efraim for the:

> Interesting read, thanks for sharing.
> Do you intend to publish it on Guix' blog?  If so, I think the tone
> might come across as a little bit too "rantish", maybe make it a little
> more neutral / balanced.
> 
> I'd also elaborate the intro / conclusion to make the context a bit
> clearer and maybe explain what you think should be done.
> 
> Cheers!
> 
> -- 
> Pierre Neidhardt
> https://ambrevar.xyz/

Efraim, thanks for your work -- I didn't mean to hijack it, honest :)
Sorry for not making it clear that I was just reformatting your post ;-/

Ah, perhaps Pierre merely clicked reply-all and he really was thanking you, Efraim,
and it just appeared to be directed toward me because of the "> Bengt Richter <bokr@bokr.com> writes:"
heading?
-- 
Regards,
Bengt Richter

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [BLOG] rust blog post
  2019-11-27  0:19         ` Bengt Richter
@ 2019-11-27  9:38           ` Efraim Flashner
  0 siblings, 0 replies; 7+ messages in thread
From: Efraim Flashner @ 2019-11-27  9:38 UTC (permalink / raw)
  To: Bengt Richter; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 1933 bytes --]

On Tue, Nov 26, 2019 at 04:19:01PM -0800, Bengt Richter wrote:
> Hi Pierre, and apologies to Efraim...
> 
> On +2019-11-26 14:01:10 +0100, Pierre Neidhardt wrote:
> > Bengt Richter <bokr@bokr.com> writes:
> > 
> > >     be a binary. Its... both? Javascript libraries leave  distro
> > 
> > Typo: "It's".
> >

It's one of the ones I have a hard time with. When I remember I'm great
with it.

> 
> I noticed that too, but it's Efraim's typo,
> as is the entire text: I merely reformatted Efraim's post
> into a sort of rfc-style, i.e., Left-and-Right-justified.

Thanks

> 
> So, credit to Efraim for the:
> 
> > Interesting read, thanks for sharing.
> > Do you intend to publish it on Guix' blog?  If so, I think the tone
> > might come across as a little bit too "rantish", maybe make it a little
> > more neutral / balanced.

Definitely wasn't aiming for rantish, I'll see what I can do about
making it better. It was more of a stream-of-consciousness typing and I
figured I could go back and rework it later.

> > 
> > I'd also elaborate the intro / conclusion to make the context a bit
> > clearer and maybe explain what you think should be done.

Sounds like a good idea.

> > 
> > Cheers!
> > 
> > -- 
> > Pierre Neidhardt
> > https://ambrevar.xyz/
> 
> Efraim, thanks for your work -- I didn't mean to hijack it, honest :)
> Sorry for not making it clear that I was just reformatting your post ;-/
> 
> Ah, perhaps Pierre merely clicked reply-all and he really was thanking you, Efraim,
> and it just appeared to be directed toward me because of the "> Bengt Richter <bokr@bokr.com> writes:"
> heading?

Likely. I normally hit reply-all for mailing list posts

-- 
Efraim Flashner   <efraim@flashner.co.il>   אפרים פלשנר
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-11-27  9:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-25 10:30 [BLOG] rust blog post Efraim Flashner
2019-11-26  9:58 ` Pierre Neidhardt
2019-11-26 10:27   ` Efraim Flashner
2019-11-26 12:26     ` Bengt Richter
2019-11-26 13:01       ` Pierre Neidhardt
2019-11-27  0:19         ` Bengt Richter
2019-11-27  9:38           ` Efraim Flashner

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.