laurent.orseau
2020-6-18 12:53:49

Core team: How did you forward http://github.com/plt/racket\|github.com/plt/racket to http://github.com/racket/racket\|github.com/racket/racket, while keeping the plt account? Did you just use the “change username” tool on github, and then (re)created the plt username too? (I’ve been thinking of getting a more descriptive username on github, but I’m worried about the consequences)


sorawee
2020-6-18 13:03:33

After building from source, what command do I use to rebuild it without messing up earlier raco pkg --clone?


laurent.orseau
2020-6-18 13:14:15

Seems to me that running make will not mess with that. I guess that kind of info is stored in your pref file/dir, and make doesn’t override this.


mflatt
2020-6-18 13:14:43

Right. It’s recorded in the package-installation information.


mflatt
2020-6-18 13:15:05

Probably @samth knows the answer…


sorawee
2020-6-18 13:35:06

Interesting. There must be something else that made me getting package conflicts


samth
2020-6-18 13:45:23

I believe we created the racket organization account, and then transferred the repository from the plt user to the racket organization.


samth
2020-6-18 13:45:55

I think in your case just renaming should preserve links


laurent.orseau
2020-6-18 13:50:55

I see, thanks


sorawee
2020-6-18 17:09:03

Ah, my fault indeed


sorawee
2020-6-18 17:09:54

I manually modified racket/share/links.rktd without modifying racket/share/pkgs/pkgs.rktd


laurent.orseau
2020-6-18 17:13:03

That seems a little risky indeed :slightly_smiling_face:


bedeke
2020-6-18 17:29:07

Hello, What would be the right type definition for the following function? #lang typed/racket/base (: test (All (A ...) (A ... -> Boolean))) (define (test . rst)(if (null? rst) #t (and (car rst) #f))) (define #:forall (A ...)(test2 . [rst : A ... A]) : Boolean (if (null? rst) #t (and (car rst) #f)))


bedeke
2020-6-18 17:30:07

both typecheck, but take the none empty branch for (test) and (test2)


bedeke
2020-6-18 17:30:42

(using racket 7.7.0.7)


sorawee
2020-6-18 17:40:15

@bedeke: (: test (All (A) (A * -> Boolean)))


bedeke
2020-6-18 17:42:07

Thanks, but I really want the rest arguments to be different types


samth
2020-6-18 18:36:38

@bedeke that looks like a TR optimizer bug


samth
2020-6-18 18:37:15

that is, when I add #:no-optimize to the #lang line, i get #t


samth
2020-6-18 18:38:39

Or, more fundamentally, this typechecks: (: test (All (A ...) (A ... -> False))) (define (test . rst) (null? rst))


anything
2020-6-18 18:38:47

I’m looking for a procedure which I’d call any. It’s a type of fold that’d say true if any of the elements of the list satisfy a predicate. (Similarly, I’m look for a procedure that I’d call all.) I can’t seem to find any such procedures in the standard libraries by this name.


samth
2020-6-18 18:39:11

@anything they’re called ormap and andmap


anything
2020-6-18 18:39:17

Aha! Thank you!


anything
2020-6-18 18:42:52

I might as well ask: why isn’t there a procedure called true? if there is one called false? in racket/bool?


samth
2020-6-18 18:44:50

in general you don’t need to look for true values because everything that’s not false is true


shane
2020-6-18 18:45:28

Hey folks, very quick question: is there a way to install a specific version of a package with raco ?


samth
2020-6-18 18:50:13

If you need to be sure that you get the version you need, you can use the --checksum option to raco pkg install. Or you can specify a version in your info.rkt and raco pkg install will ensure you get at least that version.


samth
2020-6-18 18:51:13

There’s no way to install an older version in general, but if it points to a git repository you can use the git://... package specification to pick out a particular branch or commit.


anything
2020-6-18 19:10:48

Good point. I mean, while false? is an alternative to not, false? exists while true? does not.


shane
2020-6-18 19:38:11

wonderful, thanks! I’ll give the git thing a try


bedeke
2020-6-18 19:51:09

@samth the second step in what I was trying to do was: #lang typed/racket/base (struct (A) foo1 ([a : A])) (struct (A) foo2 ([a : (-> A A)])) (: test1 (All (A B ...) ((foo1 A) (List (foo2 (∩ A B)) ...) -> A))) (define (test1 a bs) (foo1-a a)) (: test2 (All (A B ...) ((foo1 A) (foo2 (∩ A B) )... -> A))) (define (test2 a . bs) (test3 a bs)) this fails the typecheck with: Type Checker: Polymorphic function `test1' could not be applied to arguments: Argument 1: Expected: (foo1 A) Given: (foo1 A) Argument 2: Expected: (List (foo2 (∩ A B)) ... B) Given: (List (foo2 (∩ A B)) ... B) Result type: A Expected result: A in: (test1 a bs) given the error message, I’m hoping it can be achieved…


samth
2020-6-18 19:52:50

what is test3 here?


jaz
2020-6-18 19:59:43

~I think that was supposed to be test1, and I think the issue here is that the type (List T ...) requires at least 1 element.~


jaz
2020-6-18 20:00:17

… after using (inst test1 A)


jaz
2020-6-18 20:01:50

Er, after re-reading the docs, I don’t know about that…


jaz
2020-6-18 20:02:31

But the error then is: Type Checker: type mismatch expected: Null given: (List (foo2 (∩ A B)) ... B) in: bs


jaz
2020-6-18 20:04:43

Oh, that was dumb of me. I only instantiated the first type variable.


bedeke
2020-6-18 20:04:46

Ai, bad copy of code, it should be test1, ie just calling test1 with the rest arguments gathered in a list


jaz
2020-6-18 20:04:55

So, (inst test1 A B ... B) works fine.


bedeke
2020-6-18 20:06:41

oh thanks… due to the error text I forgot to try inst…


jaz
2020-6-18 20:07:25

I find it hard to predict when you need to instantiate type variables explicitly and when they can be inferred.


jaz
2020-6-18 20:08:34

And, of course, when you use the same names for your type variables and you get error messages that say: “I expected A but found A” it’s obviously pretty confusing.


badkins
2020-6-18 20:22:19

@samth you said you can install a specific version using a checksum option, but then you said there’s no way to install an older version in general. Can you clarify that?


badkins
2020-6-18 20:22:46

The reason I’m asking is envisioning a scenario where the latest version of a package has a bug, and I need to stick with the previous version that works.


samth
2020-6-18 20:22:59

I mean, you can supply the checksum command line argument, and that will verify that you get that checksum, but it won’t let you get an old checksum


badkins
2020-6-18 20:23:27

That seems quite odd.


badkins
2020-6-18 20:23:58

So you can specify a checksum of the latest version to ensure you get the latest version, but you can’t specify any previous checksum? Wow.


samth
2020-6-18 20:24:52

If you need to depend specifically on an old version, then you can depend on a package named by a specific git revision using the the syntax for that, such as <git://github.com/samth/foo#branch>


badkins
2020-6-18 20:24:53

How do folks deal with the scenario I mentioned? In the Ruby world, it’s extremely common to specify the specific version of all gems (“package”) used in a project.


badkins
2020-6-18 20:26:05

I just did raco pkg show and only two packages on my lapto end in ".git"


badkins
2020-6-18 20:26:18

Is there a way for non-github packages?


samth
2020-6-18 20:26:18

There’s been a bunch of discussion of this recently in various places, one place to look is https://alex-hhh.github.io/2020/05/dependency-management-in-racket-applications.html


badkins
2020-6-18 20:29:00

Thanks. I remember seeing some of the discussions, but I wasn’t at the point where it was a pressing issue yet. That’s changing. It appears the current situations requires some hacks, but is the long term goal to allow versioning, as with most other language ecosystems?


badkins
2020-6-18 20:55:40

I just looked through a thread on the mailing list about package versioning. If the accepted way to make backwards incompatible changes to a package is to change the package name, that’s fine. I’m used to a major.minor.patch versioning of libraries/gems/packages, but whatever. However, I’m more concerned about the scenario where a package is updated and introduces a bug. I realize a few ways to handle this have been adopted by various people, but thus far, they’ve been unsatisfactory to me. @jeapostrophe mentioned an option of <https://groups.google.com/d/msg/racket-users/4iI-SanIbzk/sGHYijLPAAAJ|creating your own package catalog> which seems interesting. If you are using this method, would you mind commenting in a thread, and if you can point me to documentation, blog posts, etc. to help me get setup, that would be great.


badkins
2020-6-18 20:57:44

For this method to work for me, it would have to allow me to pin a particular version of a package after the package has been updated w/ a bug. In other words, if I have to have already pinned a package before it’s updated with a bug, then this is a fail, but I think that’s obvious.


badkins
2020-6-18 21:01:07

By the way, I really hope the long term goal is simply to be able to specify a list of packages and their versions, and then be able to install all of those versioned packages with a raco pkg command. Ideally, this would be on a project/directory basis as different applications may have different needs. Anything else seems ridiculous frankly.


badkins
2020-6-18 21:03:54

Here’s an example from the Ruby world: https://bundler.io/



badkins
2020-6-18 21:13:06

Yes, while I appreciate that, it doesn’t seem like the right approach to me. Bundler is far superior, and we need to get there.


badkins
2020-6-18 21:13:33

We don’t want a bunch of users creating their own ad-hoc solutions to this very common problem.


badkins
2020-6-18 21:17:55

Just out of curiosity, do you manage any production apps/servers?


badkins
2020-6-18 21:19:17

Then you should be aware of the importance of configuration management, right? It’s extremely important to be able to depend on a specific set of libraries at specific versions.


badkins
2020-6-18 21:19:35

I expect Python has a similar system to Ruby’s Bundler.


badkins
2020-6-18 21:20:22

It’s exactly as prevalent as there are people managing production apps/servers, right?


badkins
2020-6-18 21:20:49

I think you’re saying you haven’t been bitten by it yet, but that’s an extremely risky way to proceed.


badkins
2020-6-18 21:24:36

Sure. Envision this scenario. You install a set of packages, develop an application, and everything is fine. Then you setup a new server, install the same set of packages (some of which have been updated), and your tests fail. How do you get the set of packages on your development machine installed on the server?


badkins
2020-6-18 21:25:26

Or, you updated packages on your development machine, and tests fail - how do you roll back?


badkins
2020-6-18 21:27:01

Right. I’m not interested in Docker.


popa.bogdanp
2020-6-18 21:33:07

@badkins you might be interested in https://racksnaps.defn.io/


badkins
2020-6-18 21:33:59

How do you handle needing packages from different days?


popa.bogdanp
2020-6-18 21:34:18

You’re forced to upgrade at that point.


badkins
2020-6-18 21:34:31

I don’t think that will work then.


badkins
2020-6-18 21:35:21

I really don’t get the resistance to a versioning system.


badkins
2020-6-18 21:38:23

Not at all - sorry for the confusion! I was referring to pushback against versioning I’ve seen in various threads.


popa.bogdanp
2020-6-18 21:39:42

I was pointing out racksnaps as a potential solution to:

> However, I’m more concerned about the scenario where a package is updated and introduces a bug. But it’s for sure not a general solution.


popa.bogdanp
2020-6-18 21:40:16

I also didn’t get the sense that there was much resistance, just nuance and folks pitching in about their experience. I’m sure if someone builds versioning atop raco pkg and it ends up being a good system, then people will use it.


badkins
2020-6-18 21:41:52

This is a related, but different question. For one scenario, it would be sufficient for me to duplicate the package environment I have on my laptop to new production servers. I see that there is a raco pkg archive command - could that be used to accomplish this? I develop on MacOS, and I deploy on Linux.


badkins
2020-6-18 21:43:04

Maybe it was just defensiveness for not having a versioning system. I suppose the main pushback is for not allowing backward incompatible changes i.e. forcing a new package name. I’m less opinionated about that.


badkins
2020-6-18 21:44:06

@popa.bogdanp to build something on top of raco pkg it seems that the current system would need to allow installing a specific version; otherwise, it seems like it might be an entirely new package system.


popa.bogdanp
2020-6-18 21:49:36

You could have a system that generates a catalog on the fly that points to specific source versions of each package. The catalogs themselves are just mappings from package names to package sources (URLs).


popa.bogdanp
2020-6-18 21:51:32

In this scenario the catalog is kind of the analog of a lockfile in other package managers.


badkins
2020-6-18 21:52:31

I guess I don’t understand how to retrieve all the source versions for a package using the current package system.


badkins
2020-6-18 21:53:20

I suppose that’s easy enough if they’re using git; otherwise, I’m not sure.


badkins
2020-6-18 21:54:08

For example, csv-reading


popa.bogdanp
2020-6-18 21:55:56

The package server would have to be extended to support that kind of metadata and to be able to host all the versions of those packages (IMO, relying on Git is not a great idea). Or someone could create an alternative package server that supports those things.


badkins
2020-6-18 22:10:00

BTW @popa.bogdanp thank you for racksnaps - I didn’t mean to be so dismissive. I think it could be extremely useful even if I can’t use it directly as intended. For example, if Neil updates csv-reading, I would have no way of getting the previous version (if I didn’t have it installed locally already), but I could grab it from racksnaps and put it into my custom catalog.


popa.bogdanp
2020-6-18 22:12:24

No worries! Also, another way to address your original question could be to layer different snapshots.


popa.bogdanp
2020-6-18 22:12:43

I hadn’t thought about it much and I’ve never tried it, but conceptually it should work just fine.


popa.bogdanp
2020-6-18 22:13:57

So say you want to rely on packages from 2016/06/14, but then a new package comes around on the 18th, you could just add the snap from the 18th as a secondary catalog.


popa.bogdanp
2020-6-18 22:14:53

Of course, that doesn’t work in many scenarios (eg. when you just want to upgrade a single package).


popa.bogdanp
2020-6-18 22:15:53

Generally, though, I’ve found that folks just don’t make many breaking changes. When they do it’s easy to upgrade and relying on daily snapshots prevents bugs from suddenly appearing.


aymano.osman
2020-6-18 22:22:19

not sure where the right place to ask this question is but I was wondering if expand supports reading in a module that has unbound identifiers. I was hoping I could use drracket/check-syntax to analyse such files.


alexharsanyi
2020-6-18 22:24:37

> We don’t want a bunch of users creating their own ad-hoc solutions to this very common problem.

@badkins I have a feeling that, while several people agree that there is a problem, there is no agreement at all as to what the problem is and how to solve it. I came up with my solution, which works for me, @popa.bogdanp came up with his, which works for him, but other people don’t find either solution satisfactory. Perhaps further concrete proposals and pilot implementations will need to appear, and maybe one will emerge as a community favourite and will become the “official” one.


badkins
2020-6-18 22:26:57

Well, I feel this is a very solved problem in other language communities. I suppose there are some subtle differences, but the problem seems clear enough to me. We have a history of operating system packages & numerous programming language package systems. I’ve used Bundler for years in Ruby, and it’s done everything I’ve ever wanted.


badkins
2020-6-18 22:29:34

I understand the strong desire for backward compatibility in the Racket community, and I think that’s a strength, so I’m personally fine with changing the name of a package when it breaks backward compatibility. I realize others feel differently, but that’s a separate problem from the issue of unintentional breakage due to the combination of bugs and package author’s delay in fixing them.


badkins
2020-6-18 22:32:02

Having said that, once you solve this more important problem (which I think requires versioning), there’s really no need to rename a package - just consider the version part of the name where a major version change indicates a backward incompatible change.


badkins
2020-6-18 22:32:41

has been called to supper, back later…


alexharsanyi
2020-6-18 22:35:19

@badkins you seem familiar wit Bundler and think it will be a good fit for Racket. Do you volunteer to provide a pilot implementation, so the rest of the community can evaluate it to see if it fits their needs?


notjack
2020-6-18 23:07:37

This question comes up often enough from people that we could just add true? and write down the explanation of why you usually don’t need it in its documentation


badkins
2020-6-18 23:11:11

Since Bundler exists already, it’s easy to evaluate - it seems to be well documented. There may be better managers, but I’m not familiar with them.


samth
2020-6-18 23:13:33

I feel like there was a recent discussion about adding it, but I agree generally


badkins
2020-6-18 23:13:57

I think they all basically do the same thing - allow specifying a set of packages with a versioning scheme that’s flexible enough to specify a variety of versions, and allow locking a set of packages at specific versions.


badkins
2020-6-18 23:14:51

Seems like the first step is to simply allow something like raco pkg install foo@2.3.7 (I stole the @ from Julia)


notjack
2020-6-18 23:18:06

not sure how much has changed since it was published, but this post is a good summary of the state of the art https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527\|https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527


mflatt
2020-6-18 23:19:15

@notjack No one is suggesting that they want to write a package manager. People only want to give advice for someone else to do it.


notjack
2020-6-18 23:19:25

yup


badkins
2020-6-18 23:19:31

C’mon guys…


notjack
2020-6-18 23:19:53

@badkins it is a full time job and then some to make one


badkins
2020-6-18 23:20:14

I’d be content for folks to simply admit it’s important to be able to install a specific version of a package.


notjack
2020-6-18 23:20:28

I think that’s important, yes


badkins
2020-6-18 23:20:55

Great, ’cause I got the sense that feeling is far from universal, so it’s a good start.


notjack
2020-6-18 23:24:09

I also think getting to that point will take a lot of work, way more than I’d be able to do as someone who writes Racket in my spare time for fun


notjack
2020-6-18 23:24:53

and this is coming from someone who works on CI systems for a living


badkins
2020-6-18 23:37:04

So @mflatt before I invest more time in this, is it safe to say the core team would be interested in enhancements to raco pkg that allow for 1) installing a specific version of a package, 2) specifying a set of versions for each dependency package, and 3) having a versioning scheme such as &lt;major&gt;.&lt;minor&gt;.&lt;patch&gt; where a bump in major number may break backward compatibility?


badkins
2020-6-18 23:45:49

Rather than reinvent the wheel, I’d probably just go with RubyGems versions specifiers for dependencies: Most of the version specifiers, like &gt;= 1.0, are self-explanatory. The specifier ~&gt; has a special meaning, best shown by example. ~&gt; 2.0.3 is identical to &gt;= 2.0.3 and &lt; 2.1. ~&gt; 2.1 is identical to &gt;= 2.1 and &lt; 3.0. ~&gt; 2.2.beta will match prerelease versions like 2.2.beta.12. ~&gt; 0 is identical to &gt;= 0.0 and &lt; 1.0. https://guides.rubygems.org/patterns/#pessimistic-version-constraint


samth
2020-6-18 23:47:00

@badkins I think that while people would like something like bundler, there are some tricky issues that make it not obvious what the best design for Racket is


samth
2020-6-18 23:47:25

Or, I should say, people would like the properties that bundler provides, as you say


samth
2020-6-18 23:48:09

I will try to write down some more of my thoughts here later this evening


badkins
2020-6-18 23:48:25

Bundler-like functionality wouldn’t be the first step. I’d rather build the bare minimum that makes sense to allow the fancier functionality to be built upon it i.e. the primitives.


mflatt
2020-6-18 23:48:33

@badkins I would say that everyone (core team included) would be interested in a worked-out implementation that does those things.


badkins
2020-6-18 23:50:01

Awesome. I’m basically married to Racket for the long term now, so I’m going to need this eventually. For right now, I just need to solve the “I need these specific packages at these specific versions” problem regardless of how ugly/manual, but I’m happy to get involved in a longer term project that ends up with something like Bundler. I think I misread comments as pushback, so glad to hear I was mistaken.


samth
2020-6-18 23:50:27

I also have an idea that I think would accomplish the key thing you want without much change at all, but the kids have to go to bed first


badkins
2020-6-18 23:50:53

I think @jeapostrophe’s “personal catalog” idea may get me there once I figure it out…


badkins
2020-6-18 23:51:52

The non-git packages are a bit of a pain, but maybe racksnap will provide what I need there re: getting a previous version of a non-git package after the author has updated it an overwritten the package source with the latest.


badkins
2020-6-18 23:53:39

I’m also wondering if an existing package manager couldn’t be leveraged. I don’t really see why something like Bundler couldn’t be used for another language, but I may be missing something.


alexharsanyi
2020-6-19 00:01:56

If you are looking for a personal package catalog, you can just place packages you need in the same directory (use one directory for each package) and use the pkg/dirs-catalog command to create a catalog for these packages. The blog post that I wrote uses essentially this approach, with the added step that the packages are managed as git submodules. However, you can ignore the top half of the blog post, and the bottom half will show you how to create a personal catalog.


badkins
2020-6-19 00:02:50

Thanks, I noticed that part of your blog post after I asked the question above. What’s the best way to install packages on a server using that catalog?


badkins
2020-6-19 00:04:37

I think the personal catalog approach is the 80/20 solution I need for now, and the web framework is both a higher priority, and something I’m better at, than a package manager. I’d probably be more likely to provide funding for the latter if push comes to shove.


alexharsanyi
2020-6-19 00:20:53

The remaining 20% is to use git and clone the directory with packages onto the server — note that putting them somewhere else would not save you anything as the source code for the packages still needs to be downloaded.


alexharsanyi
2020-6-19 00:22:20

There are also ways to create binary packages (which are tied to a particular Racket version and dependent packages) and put those in a catalog — this would make installation and deployment faster, but managing them would be more complex — I have not looked into this, so you’ll need to read the Racket documentation for how to do this.


badkins
2020-6-19 00:24:14

I’d rather not manually load packages into git. If I have a well tested set of packages on my laptop, I think I can raco pkg archive - the docs state this will create a catalog from installed packages. Then I just need to provide access to that on the server. I suppose a worst case scenario might be scp’ing the directory to the server ?


badkins
2020-6-19 00:25:53

Oh, it looks like you have to manually list all the packages with that approach :disappointed:


alexharsanyi
2020-6-19 00:27:22

you can create one “meta package” which depends all the packages you need, and archive that one, including all its dependencies


badkins
2020-6-19 00:28:28

Gotcha. I should probably make my app a package, then I could just archive it w/ dependencies. I’ve been putting that off…


lexi.lambda
2020-6-19 00:57:15

@badkins About a year and a half ago, I wrote this comment about what concretely would need to be done to move towards a more Bundler-like world for Racket package management. I think it’s all still relevant, if you are interested. https://www.reddit.com/r/Racket/comments/9rn5ms/raco_package_versioning/e8jx6ws/


lexi.lambda
2020-6-19 00:58:23

I don’t think the required effort to get something useful is that huge, since as I said, a lot of the technical foundations are already in place. But it’s big enough that nobody has done it.


badkins
2020-6-19 00:59:14

Awesome - thanks. I really need to finish my web framework first, but package versioning may be the next thing I get involved in after that.


badkins
2020-6-19 01:00:04

I’m not sure I can attract non-lisp folks with the web framework (doesn’t matter to me), but if I did, and they came from Ruby, Elixir, Python, etc., they’re going to want versioning very soon :slightly_smiling_face:


badkins
2020-6-19 01:05:47

@lexi.lambda long-term, I would certainly want what you describe in point 1, but I’d be fine with that coming later. #’s 2 & 3 would be a higher priority for me


lexi.lambda
2020-6-19 01:06:50

FWIW, I think point 1 is actually likely to be the easiest of those points to implement, since sandbox tethering already provides most of the required functionality. But I could be wrong.


badkins
2020-6-19 01:07:09

I worked for years in a mode where I had multiple active projects with wildly different versions of libraries, so both Bundler and rbenv/rvm were very handy for having tons of different versions of ruby and various gems, but that’s unpleasant :slightly_smiling_face:


badkins
2020-6-19 01:07:44

Right now I just want to lock down packages so they’re the same on my dev machine and server.


lexi.lambda
2020-6-19 01:09:04

Yeah, that makes sense. But just FYI, I think the Bundler model of generating a per-project bin/ directory with launcher executables that configure everything properly would work really naturally with the way the existing Racket infrastructure is set up.


badkins
2020-6-19 01:09:18

Good to hear.


badkins
2020-6-19 01:09:51

I’d be most competent on #2 at the moment.


lexi.lambda
2020-6-19 01:10:29

Yeah, I think most of the challenge of #2 is getting the UI right and handling backwards-compatibility gracefully.


lexi.lambda
2020-6-19 01:11:03

The actual protocol changes should be very straightforward.


samth
2020-6-19 01:30:23

First, here’s some overall thoughts. I think people with experience in other language package managers mostly miss the following things: 1. Being able to record the packages they depend on, and then check in something so they get the same packages when they rebuild in a different environment. 2. Having a per-project scope for packages, and being able to install different versions of a package for different projects. 3. Being able to specify specific versions of packages that you depend on, and have the package installation mechanism figure out appropriate versions of everything to install 4. Being able to have two different versions of a dependency appear in your dependency tree while everything keeps working.


samth
2020-6-19 01:31:25

There’s also providing a smoother way of handling backwards incompatible changes, but I think that’s fundamentally separable


alexharsanyi
2020-6-19 01:39:46

From my personal point of view, I care about (1), (2) and (3). I have solutions for (1) and (3) (some might call them workarounds, but I am happy with them), but (2) would be nice to have.


alexharsanyi
2020-6-19 01:42:42

Also, (2) might be achievable, as suggested here: https://groups.google.com/d/msg/racket-dev/dHAFwzlFwNA/xfVGxIYaAgAJ, but I didn’t have time to explore that option


samth
2020-6-19 01:51:55

I think the solutions for each of these ends up being pretty different, and it’s important to think about the different goals here. For 1, which is the problem that is most likely to cause things to go badly wrong, people have built a number of tools, such as racksnaps and the catalog mechanism in general, and @alexharsanyi has demonstrated how to put things together. But I think there are some other simple things that would help. For example, a tool could rewrite your info.rkt file to change the dependency on “foo” to one on "<git://github.com/bar/foo#hash|git://github.com/bar/foo#hash>". Then, assuming that repository stays in place, new installs would get exactly the same package content. Of course, that’s not perfect, but it could be further improved by adding a lock file that was separately consulted by raco pkg install. Another simple thing would be for each dependency to allow specifying which catalog to look in — then you could use different racksnaps for different packages. None of these changes alter anything fundamental, but they would make the deployment safety use case easier.


samth
2020-6-19 01:59:50

For 2, the question is how much you want to share. If you don’t care about any sharing, you can just have multiple racket installs and never use user scope (this is basically what I do). The tethering approach @mflatt described lets you share more, but all the installations have to share the same version of everything shared, and everything those packages depends on. One question in this situation is the role of DrRacket. Basically, if different projects need different versions of one of DrRacket’s dependencies, then you’d need multiple copies of DrRacket.


samth
2020-6-19 02:03:19

For 3, some bigger changes to the protocol are required — the server needs to remember how to get past version, and has to know when a new version has been released. http://pkgs.racket-lang.org\|pkgs.racket-lang.org doesn’t store package content, and I don’t think we want to change that, so that’s one constraint. However, I think something in this area is doable, but it would be a lot of work in a number of places.


samth
2020-6-19 02:12:56

For 4, I think it’s much harder. There are two big challenges that I see. One is that the collections system assumes that collection paths are unique, and installing two versions of the same package would almost certainly break that. The other, more subtle issue is you’d probably end up with bugs related to the two copies trying to interact and failing, typically because the different struct definitions would produce distinct types. This is a fundamental problem with this idea in any language, but most other languages don’t have it as bad as Racket. In Haskell or Rust, either the incompatible type is exposed in the interface or it isn’t. If it isn’t, there’s no problem, and if it is, there’s a type error. In Python or JS or Ruby, typically values from external libraries are treated structurally, ie using duck typing. So the instances play well together in most cases. Racket is somewhat unique in being untyped but relying heavily on nominal tags. Of course, even in other languages two versions of a package could do something weird and conflict using the filesystem or other hidden state in a way that caused subtle bugs, but it’s much rarer. Notably, this is a problem that came up regularly with PLaneT, the previous package system. There ended up being some metadata that said whether this meant the two installs should be prohibited, but there’s only so much that this can really be solved.


samth
2020-6-19 02:18:58

Finally, on the issue of backwards incomparable changes, I think this could be addressed by having packages grow an additional field (say edition) which would basically be part of the name, except that you’d write it separately in the info.rkt file and all the different editions of a package would show up together on the package web site. This would be a pretty small change to the system but would make this use case much easier to handle than currently, where you basically add a digit to your package name. Note that widespread use of this would exacerbate problem 4 above (one reason that I prefer the “maintain compatibility” approach).


samth
2020-6-19 02:21:56

Well, that was a lot of text. Hopefully that helps, @badkins. And I’m interested in other people’s thoughts who are interested in the package system @lexi.lambda @popa.bogdanp @notjack And I should say that I’m potentially interested in implementing some of the simpler ideas for 1 & 2, but it is not at the top of my stack right now.


lexi.lambda
2020-6-19 02:23:44

I think the comment I linked above (which you responded to, so I know you read it at one point) is essentially consistent with what you’ve just written, albeit it doesn’t include a direct analog to point 1.


jaz
2020-6-19 02:24:14

IIRC, bundler (and some other package systems) don’t attempt to solve (4); they require that the dependencies of a given application agree on a single version of any one package.


jaz
2020-6-19 02:25:06

Though not solving that problem adds a different one: figuring out which, if any, version can be used given all the dependencies.


lexi.lambda
2020-6-19 02:26:57

Yes, I agree; my comment proposes a Cabal-/Bundler-esque model, not an npm-esque one. The latter seems theoretically useful but very hard to get to from where we are right now, and I don’t think it’s essential to the usefulness of the system.


lexi.lambda
2020-6-19 02:31:12

I do think your explicit discussion of DrRacket is a very good point that I didn’t mention explicitly. In some ways it is rather at odds with the DrRacket philosophy: it would mean having a DrRacket installation per project, but DrRacket is supposed to be an operating system! Historically Racket has gone to great lengths to allow DrRacket to run everything in-process, without the need for some extra-linguistic mechanism, but this would be an explicit compromise on that point.


lexi.lambda
2020-6-19 02:32:08

That said, I think the current package system is already an explicit compromise on that idea, relative to PLaneT. So that isn’t really new, it’s just a deeper ramification than we’ve seen so far.