tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)

I got my week off to a good start by restoring a "new" laptop from my TimeMachine backup, for the second time in about ten days. (After last week's 193 million memory errors.)

After the restore (which took about an hour, fortuitously coinciding with the weekly all-hands meeting) I started my three Rust workspaces building, and after some strategic sledgehammer (removing-the-build-directory) applications, that actually succeeded. So I went back to alternating between work on rustpkg and the typechecker refactor, as build times permitted.

I actually made some progress on rustpkg: last week I'd started trying to port an example of a custom Makefile into a package script instead. The example package I'm using, rust-sdl, currently has a Makefile with this rule (which only fires when building on Macs):

$(SDLXMAIN): $(SDL_PREFIX)/libSDLmain.a
        $(CP) $< $@
        $(AR) -x $@ SDLMain.o || $(RM) -f $@
        $(LD) -r SDLMain.o -o SDLXMain.o -alias _main _SDLX_main \
             -unexported_symbol main || $(RM) -f $@
        $(MV) SDLXMain.o SDLMain.o || $(RM) -f $@
        $(CHMOD) u+w $@ || $(RM) -f $@
        $(AR) -r $@ SDLMain.o || $(RM) -f $@
It's not for me to ask why; anyway, being fairly simple, this made a good example for me. I transliterated it into Rust like so:
const SDL_PREFIX : &static/str = "/usr/local/lib";

#[pkg_do(post_build)]
fn post_build() {
 // todo: delete new_sdl_lib_name if any commands fail
    let existing_sdl_lib_name = path(SDL_PREFIX).push("libSDLmain.a");
    let new_sdl_lib_name = path(SDL_PREFIX).push("libSDLXmain.a");
    let sdl_obj_file = ~"SDLMain.o";
    let sdlx_obj_file = ~"SDLXmain.o";
    copy_file(existing_sdl_lib_name, new_sdl_lib_name);
    archive_file(Extract, new_sdl_lib_name, sdl_obj_file);
    load_file(sdl_obj_file, sdlx_obj_file, ~[(~"_main", ~"_SDLX_main")],
              ~[(~"_main")]);
    move_file(sdlx_obj_file, sdl_obj_file);
    change_file_permissions((User, Writable), new_sdl_lib_name);
    archive_file(Extract, sdl_obj_file);
}
This is still sketchy and I haven't actually implemented most of the functions above yet. But the basic idea for what we're trying to do in rustpkg is that as much functionality as possible should be in the Rust build system; you shouldn't need to write a Makefile even to do something fancy.

So I spent that part of today trying to make this work. It doesn't yet, but I did get up to the point where rustpkg fails with a resolve error -- when calling out to compile the code in the package script -- because the functions I didn't implement yet aren't defined. Most of that time was spent defining a new version of rustpkg's PackageScript structure that has a PkgId field instead of a name field and a version field. PkgIds just bundle together the name and version of the package, both of which now will be inferred from the directory name (or version control info if present) if not declared. (The existing version of rustpkg that's up on github requires you to declare your package's name and version explicitly.)

The typechecker situation is sadder; I fixed my bad merges and ran tests, only to find that one of the run-fail tests was failing with a nondeterministic error:

  • Assertion failed: ((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"), \
        function CreatePointerCast, \
        file /Users/tchevalier/rust3/src/llvm/lib/VMCore/Instructions.cpp, \
         line 2385.
    
  • error: internal compiler error: Asked to compute contents of fictitious type
  • rustc(29409,0x107cca000) malloc: *** error for object 0x7fdd9ba19f80: pointer \
        being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    
  • Assertion failed: (box->td != NULL), function free, \
       file /Users/tchevalier/rust3/src/rt/boxed_region.cpp, line 75.

These are all different error messages that I got on different runs of the same test. Because this behavior looked so similar to what was happening on the other, broken laptop (though with a different test), I thought maybe this one was borked too. What are the chances of that? It's like in the joke that goes "I always bring a bomb with me when I fly, because what are the chances of there being two bombs on the airplane?" Running valgrind, though, assuaged that fear, since it actually worked (and reported a metric crap-ton of invalid reads), as opposed to declaring its inability to execute rustc (like on the broken laptop). The errors suggest some sort of memory corruption having to do with types, which isn't totally surprising since rustc represents types in a totally unsafe way, and it would be easy to get something wrong. It's still puzzling me that I can get so many tests to work with only one failing if I introduced a bug like that, though. Usually, these kinds of failures are catastrophic.

Anyway, progress, in that I closed the day with a laptop that isn't obviously broken, unlike last Friday...

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I spent too much of today dealing with an apparent hardware failure on -- irritatingly enough -- the laptop I'd borrowed from IT to replace the laptop I was using for the past almost-a-year, which just before I left for Vancouver decided it didn't have a wifi card anymore. Most of yesterday I was trying to debug an issue where I was getting non-deterministic segfaulting and also occasional not-seeing-the-bug-I-was-looking for. Graydon suggested that I run memtest86, and so I did... and it reported 193 million errors before I decided that was enough. So then I sshed into a buildbot that Graydon decommissioned temporarily, and moved my working directories onto it.

After which, I found the bug! I'm not happy with my fix, though. So you may recall that a while ago, I introduced a ty_err type to represent a value that can't be typed and allow the typechecker to typecheck other parts of the program before finally reporting all the errors. The fix I was working on was to never represent a type like () -> ty_err -- a function type where the result type is erroneous -- because this should just normalize to ty_err; a type with a component that was erroneous is erroneous itself. The problem is that a type might look like () -> α, where α is a type variable, and if α gets unified with ty_err at some later point in time, the way the Rust typechecker works makes it hard to see how that information gets propagated back to anyone who might have a copy of () -> α sitting around.

My solution was just to call a function that resolves all type variables in the type at the point where we've just checked the body of a closure, and write the resolved type back in for the closure. But this is unsatisfactory to me because I haven't really thought about whether this is the only point in the typechecker where that needs to happen.

The whole approach is probably wrong and misguided in some way I don't quite understand, and then I decided it was a good idea to rebase my branch for some reason, which resulted in conflicts and quite possibly a bad merge by me. I think that means it's time to leave for the weekend.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I succeeded at moving to Vancouver! A bit of culture shock. (Feel free to come up with a joke about moving out of a mutable reference or something.) I'm only here for less than three months, so I'm trying to absorb as much of Graydon's knowledge as possible in the meantime.

Continuing to work on the typechecker refactoring (yes, still); running up against very frustrating sporadic segfaults that I'm pretty sure are not to do with my changes, and that's about the most frustrating thing that can happen.

I also started working on rustpkg to finish up the work that our valiant volunteer Zack started. So far, trying to get rustpkg to build rust-sdl. Since rust-sdl requires some custom build logic -- currently implemented in a Makefile -- to rename the library file on Macs, I figured that might be a good starting point for porting that into build logic implemented in Rust that rustpkg can run. Or not; I still don't really know what I'm doing yet.

Figured I'd prioritize resuming regular posting ahead of making informative postings ;-)
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
When I was a grad student at Portland State, during 2008-2010, I took a second job in addition to my research assistantship, doing scientific and technical editing for a company called American Journal Experts (AJE). AJE hires grad students to copy-edit academic articles written by authors whose first language wasn't English. The rates they pay are very low -- because the rates are based on the article length rather than on time spent, and because many papers were in seriously poor shape, I usually found it necessary to spend so much time on a single paper that my rate came out to minimum wage or below. But, it was a job I could do from home at any hour of the day, and because my research assistantship didn't come with health insurance, I had very little choice but to take a second job so I could pay the student health insurance premiums (which tripled in cost during the four years I was at Portland State).

Anyway, AJE hired grad students as independent contractors, and for all I know, they still do. However, in the US, "independent contractor" is a term with a very specific meaning. A company can't just hire anybody they want to as a contractor -- they have to follow certain rules for how they treat that individual. As AJE began to exert more and more control over how I did my editing work, I began to think that I was really an employee, so I filed an SS-8 form with the IRS to request reclassification as an employee. That was in April 2010.

I never got a reply from the IRS beyond the initial one saying my letter had been received... until this past weekend, when I happened to be at my former housemate's house for a party and she handed me a letter that had been sent to me there. The letter was dated January 2013 and in it, the IRS stated that I had indeed been an employee of American Journal Experts, as per the legal definition of what "employee" and "independent contractor" mean in the tax code. The letter also stated that normally, the IRS tries to get both sides of the case in an SS-8 reclassification -- the employee and the employer -- but that AJE never replied to their request. I guess this may have been why it took more than two and a half years for the IRS to process my SS-8. (I was surprised by the length of time, since in 2006 when I requested (and was granted) reclassification as an employee after I'd worked as a contractor for Laszlo Systems, I received a response from the IRS very promptly.)

What this means for me concretely is that although I paid self-employment tax for the years when I worked for AJE, I didn't really have to, because AJE should have been paying half of my FICA taxes. Unfortunately for me, the statute of limitations on tax refunds is three years (from when I filed my return), so I can only file an amended return for 2010; 2009 and 2008 are water under the bridge.

This means something for a lot of other people as well: AJE has hundreds of grad student contractors, or rather, employees, and because their jobs are no different from my former job, they can all file SS-8 forms as well. I don't know what will happen if AJE continues to hire new employees while misclassifying them as contractors.

To help anyone who might want to do this, here's a PDF link to my filled-out SS-8 form that I submitted in 2010. The form mentions an auxiliary letter, and here's another PDF containing both that letter, and the reply I received from the IRS 2 1/2 years later. The IRS really gets a bad rap, but both times I've gone through the SS-8 process, I've been impressed by the clarity and thoroughness of the letters I've received in response. My auxiliary letter mentions some supporting documents that I haven't included in the PDFs, but if you want to see the whole package for whatever reason, let me know.

At this point, you might be saying, "what's the big deal, Tim? Don't companies abuse independent contractor status in this way all the time?" Yeah, they do, but I think it's a big deal every time that they do, because every time that they do, it's one more reminder to all of us that corporations get all of the privileges of being people and none of the responsibilities. If people (specifically poor and working-class people and people of color) get punished when they break the law, corporations should have to follow the law too, whether or not they like the laws, and whether or not the laws are convenient to follow.

Feel free to pass around this link to people -- it's public -- either because they've worked for AJE, or because they've done similar work, or just because they want an example of a filled-out SS-8.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I fixed the tests that weren't working yesterday in the typechecker refactoring branch, and I'm running the test suite again -- a few compile-fail tests have failed already, but those should be fun to figure out. (So far I see a few ICEs due to the fact that we're continuing typechecking in more places now, rather than returning early because of seeing an error type.)

My post from yesterday got a few more comments than usual! I'm always glad to get comments on my Rust posts, especially since it can be hard for people who don't use Dreamwidth regularly to comment on my blog, so I appreciate any effort towards that end. Here's how to comment if you don't have a Dreamwidth account.

Also along those lines, I'm well aware that my Rust posts swing wildly back and forth between explaining basic terms and assuming you know about things that you'd only know about if you'd read some obscure module in rustc::middle -- so if you're curious about anything, please don't assume you "should" know what it means and please do ask questions!
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Almost finished with the big typechecker refactor. Or the typechecker refactor of moderate size, anyway. Getting libcore to compile with the refactored typechecker was painful, but once I got there, I got all the way through building stage1 and most of the run-pass tests! The first round of tests that failed were:
failures:
    [run-pass] /Users/tchevalier/rust3/src/test/run-pass/unreachable-code-1.rs
    [run-pass] /Users/tchevalier/rust3/src/test/run-pass/unreachable-code.rs
    [run-pass] /Users/tchevalier/rust3/src/test/run-pass/weird-exprs.rs

There was something satisfying about that. Little weird-exprs tests doing their job.

As for why the unreachable-code tests failed: trans (the part of rustc that translates Rust to LLVM) tries to use type information to avoid generating code for unreachable Rust expressions. This is all pretty ad hoc, but since we have the _|_ type in the type system, why not use it?

The expression in this case looks like return + 1. In the old typechecker, if you looked up the type for this instance of 1, it would have been int or uint. But return always returns and arguments to + in Rust are always evaluated left to right, so we know that the 1 is unreachable here. So the new typechecker says 1 has type _|_ in this context.

That caused the code to translate int literals to complain, since it's not expecting an int to have type _|_. Why would anyone write code like this, you ask? They probably wouldn't, but macros could.)

So I'll just make trans more consistent in when it avoids generating code for unreachable expressions. Arguably it might be better to make trans not approximate what code is unreachable and just treat _|_-typed things as if they are reachable and generate code for them, but that's a change for another day.

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
A few weeks ago, I agreed to be interviewed by a reporter for CNN Money (online only, there's no TV version of this as far as I know) about my financial situation -- the Transgender Law Center put me in touch with her. Of course, I would rather make the news for something other than being in massive debt, but I'm hoping this will help raise awareness of something like that. Here's the article, which goes with a slide show of me and five trans women, with each of our stories in our own words. I can't speak for any of the other five participants, but I was pleased with the level of accuracy with which Blake Ellis, the author, transcribed my words as you see them on the page.

Despite my net worth being in the negative five figures, I still try to donate to organizations I support, and (while doing my taxes for 2012) I had occasion to make a list of them. These are not the only organizations I've supported, but they are my favorites. Here they are, in case you have more money than you know what to do with and want suggestions.

Scarleteen

I wish I'd had access to this site when I was 12 or 13. (I still thought that "oral sex" referred to kissing at that point.) In a country where whether teenagers should get accurate information about sex in school is a controversial subject, sites like this are sorely needed. Scarleteen is a labor of love by Heather Corinna, whose online presence I've been following for a while now, and her commitment and dedication to maintaining the site for minimal reward is inspiring.

The Ada Initiative

Open-source and free software communities, as well as free culture projects like Wikipedia, continue to be hostile environments for women, people in gender, sexual and romantic minorities, and lots of other people who are from groups that have outsider status. It doesn't have to be that way, and it would be better for everyone if everyone who had desire and energy to contribute was able to participate in building the future without fear of humiliation. The Ada Initiative is the only group I know of that is specifically working to make that vision a reality. I have had the pleasure of meeting and interacting online with both of the founders, Mary Gardiner and Valerie Aurora, so I have particular confidence in TAI's effectiveness.

National Network of Abortion Funds

Incredibly, getting an abortion in the US in 2013 is still highly dependent on one's income, and we still are a nation where being forced to give birth to a baby because of inability to pay around $500 (or in many locations, thousands of dollars when travel costs are factored in) is far from unheard of. The National Network of Abortion Funds focuses specifically on funding abortions for people who can't afford them, as well as changing unjust laws like the Hyde Amendment. They are sometimes good (not perfect!) at using language in their publicity that acknowledges that people who get pregnant and need abortions aren't always women. Stacey Burns, the online communications manager for NNAF, friended me on Facebook after I did a Causes.com birthday wish for NNAF a few years back, and through reading her posts, I've gotten a good sense for the kind of activism that NNAF represents, and that it's something I want to support.

All Hands Volunteers

In the summer of 2010, I went to Léogâne, Haiti for six weeks to help with earthquake relief. All Hands Volunteers was the group I volunteered with. I ended up leaving Haiti after four weeks instead of six -- turns out heavy labor in extreme heat wasn't the thing I was best at (and after years and years of sitting at a desk 40+ hours a week -- who'd have guessed?) While I was there, though, I saw firsthand that All Hands is a group that's very effective at getting a lot of work done with a small group of very committed volunteers. Since then, they've initiated disaster relief projects in the Philippines as well as post-Sandy relief in Staten Island and Long Island. Some of the volunteers I met while working with All Hands were among the most inspiring people I've ever met.

Lyon-Martin Health Services

I'm biased -- Lyon-Martin, in San Francisco, is where I get my primary health care. It's a place where I can feel confident that I won't be treated awkwardly or be forced to educate about being a man with a transsexual body, and it's also a place where trans women, queer cis women, and genderqueer people can feel confident of the same. They operate on a shoestring and were close to shutting down not long ago. You should give not just if you want to support respectful health care in the Bay Area, but also if you want to make sure that the informed-consent model for trans health care spreads further.

Partners in Health

Years ago, I read _Mountains Beyond Mountains_ by Tracy Kidder (on the recommendation of a LiveJournal friend!), a biography of Paul Farmer -- who, along with Ophelia Dahl, founded Partners in Health -- and it has affected my thoughts, if not yet my actions, ever since. Paul Farmer's belief in and work towards providing the same health care to poor people that (say) a Silicon Valley software engineer like me would expect for themself or for their friends and family is challenging and is a source of hope. I also appreciate that while PIH is non-sectarian, it's inspired by liberation theology; _Mountains Beyond Mountains_ quotes Farmer as saying that he knew there had to be something to religion, because rich people hated it and poor people derived strength from it. I like that. And PIH gets stuff done (plus, Ophelia Dahl graduated from my alma mater, Wellesley, reminding me that not everyone from my school becomes an investment banker).

Transgender, Gender-Variant and Intersex Justice Project

There are big-name organizations that call themselves "LGBT" when the "T" really stands for transmisogyny and the B is silent, but the TGI Justice Project is the real thing. Just as PIH focuses on providing health care where it's needed the most, TGIJP focuses on the needs of that subset of the "LGBTIQ" cohort who need justice the most: trans women of color who are or have been incarcerated or who are targeted by the criminal justice system.

Having written this list, now I'm looking forward to having my debts paid off so I can support all of these organizations more thoroughly! If you particularly want to support organizations whose work is of a global nature, Partners in Health and All Hands Volunteers are your best bets on this list. Most of my favorites are US-centric, though, since I believe in helping with the needs that I'm most familiar with (since who else is going to but the people who are affected?)

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I'm mostly done with the typechecker refactoring I talked about in my last post, though when I say I'm done I mostly mean I'm done getting it to compile. Tests passing is another matter! Plus, with a change like this, there's the nagging fear that (since we don't know what our test coverage is like) some subtle bug will slip through the cracks. I guess that's what code review is for.

In the meantime, bug triage! I spent my bug triage time today just looking at new bugs, although I'd been hoping to come up with a slightly shorter list of critical traits-related bugs for 0.6.

In the meantime, though, I'm going to prioritize these five trait-inheritance-related bugs:Altogether, there are 40 open bugs labeled "traits" with the 0.6 milestone. I hope some of these are duplicates. I'd like to fix as many as possible, but I don't know how hard it will be.

There's also my pending work on 4678 -- refactoring how "self" and type parameters get handled -- which I really don't know how to make progress on; I have to talk to Niko about it when it's not late at night in his time zone. I'm thinking that maybe if a trait A has n type parameters -- including self -- then a *reference* to T (like in fn f<T: A>) should only require n - 1 type parameters. That seems weird, though, since the point is "treat self like any other type parameter".
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I fixed #4736, which was easy enough, but that led to an adventure in refactoring the Rust typechecker.

Right now, most functions in the typechecker associate zero or more node IDs with types as a side effect (in a hash table that gets passed around), and return a bool. Every node in the abstract syntax tree (AST) has a node ID that identifies it uniquely.

The bool return value denotes whether or not the expression diverges. You can think of what that means like this: there's a primitive called fail, and fail or anything that definitively invokes fail diverges. (It's a little more complicated now because fail is a macro, but never you mind.) That information gets used to warn about statements that are statically known to be unreachable.

At the same time, one of the types that exists in the internal representation of types is ty_error, which represents an erroneous value. Normally a typechecker would abort at the first error it sees, but we want to report as many errors as possible during one compilation session, so we need a name for the type that erroneous subexpressions have. We need it because otherwise we end up reporting derived errors -- errors that are because ty_error doesn't match some other expected type. But if we saw a ty_error, we know we already reported an error about it, so we don't need to report lots more errors and overwhelm the programmer.

#4736 was because there was code that needed to execute to fill in certain data structures in error cases -- solely so we can keep typechecking and try to report more errors -- but it was getting skipped, reflecting an assumption that a certain error was fatal when it wasn't. At the same time, there were some missing checks for ty_error, so derived errors were getting reported.

But then I started thinking that I wanted to make the handling of ty_error more principled, so I changed the bool return value to a three-valued type that I called Outcome. An Outcome is either a ProperType (no errors), a BotType (saw something that diverges, which is not necessarily an error) or a TypeError (saw a type error). So in addition to the types that get written to tables as a side effect, typechecker functions now return an Outcome. This works, and is hopefully going to make it less likely for more derived errors to get reported accidentally.

But then I thought: why do we need a separate return flag in the first place? No function should ever return a type with a sub-component that is ty_error -- in that case, it should just return ty_error. For ty_bot, it's a little more complicated: for example, the expression true || fail!() doesn't always diverge (in fact, it never does) even though one of its components does. Nonetheless, I think if an expression isn't known to diverge, we don't need to know if any of its subcomponents are known to diverge.

The reason why the flag needs to be there right now is that the typing rules (as manifested in the typechecker) are non-compositional. We need the flag because we need to track information about an expression that isn't reflected in its type. But I think that's a bad code smell.

So I'm going to take a stab at making the rules compositional, which means that typechecker functions will return unit instead of bool or Outcome. This shouldn't be hard, because the internal representation of types already has a flag that says whether it contains ty_error -- so I can just make the constructors smart and return ty_error for anything whose representation would contain ty_error (like ~[ty_error]). It's a little harder to handle ty_bot correctly, but it shouldn't be too much harder.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Well, I got my twitter archive, and after checking the contents into a private github repo, I figured that the best use of the next few hours (over a few days) would be to choose my favorite tweet per month that I've used Twitter. In 2010 I pretty much only @-replied to a few people and didn't make any new tweets, but then in March 2011 when I started at Mozilla, I started using it more.

Just pasting the raw results since I've already spent enough time on this :-)
Read more... )
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I've submitted a proposal to the Open Source Bridge conference to give a tutorial talk on Rust. I can still edit the proposal between now and March 2, so I'd welcome any comments or suggestions about it!
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
A few days ago I was listening to some Vienna Teng albums on Spotify, and her song "City Hall" came up. I realized that this post -- from my LiveJournal on February 16, 2004 -- was almost nine years old. So here it is, nine years today.

If I try to think back, I don't think I thought then that we'd still be fighting for basic dignity and respect nine years later, at least not with respect to the particular issue of whether marriage should be for everyone.

We went to City Hall, in San Francisco, and helped same-sex couples get married! And I met [livejournal.com profile] ubiquity, who I hadn't expected to see at all despite having read her post where she said she was coming here this weekend, since at that point I didn't know I was also going! ([livejournal.com profile] karenbynight and [livejournal.com profile] yakkette apparently got turned away due to an excess of volunteers, and [livejournal.com profile] wkfauna -- wisely given the former -- decided not to make the trek up. And I must thank [livejournal.com profile] wintersweet, who was there on Saturday to perform ceremonies, for passing along the information so that I could be there in the first place!)

We'll display our Assessor-Record Volunteer nametags proudly in the house, though neither of us did much assessing or recording. We handed out donuts for the first few minutes -- if there's anything happier than handing out Krispy Kremes to people taking advantage of their first chance to get married, I don't know what. For the rest of the day we stationed ourselves along the line of people waiting and checked their license application forms for validity. This was surprisingly important, since many people don't understand the concept that when they say "the name on your ID has to match the name you put on the form *exactly*", they mean "don't put down 'John Jacob Jingleheimer Smith' when your license says 'John J. Smith'."

We also had to check that they'd received the booklet on "Your Future Together" that the state is legally required to hand out, and which mostly consists of information on pregnancy (not particularly relevant, since although same-sex couples might have kids, they probably wouldn't do it accidentally) and STDs (which unmarried same-sex couples presumably know more about than married different-sex couples). As one guy commented, "We've been together 24 years." And then there was the couple both of whom were named Kenneth and both of whom were over 60, of whom the older one couldn't remember what his occupation was (he'd put down "Retired" but they wanted the previous job in those cases), and the couple whose members had the same birthdays as David and I (not the same years), and the guy who had to ask his partner what his own occupation was because he forgot...

If I were ever inclined to believe that marriage was love, today would have been that moment. And it's somehow inconceivable to think of the people who will presumably be suing tomorrow in order to protect marriage by stripping 2500+ people of their marriage licenses. I wonder how many of them are just parroting lines they've been told and have never actually met a gay person and can therefore believe that they're all purple-furred monsters with horns, and how many of them actually could have stepped inside City Hall today, watched and listened to what was going on for five minutes, and still believe that letting (mostly) normal-looking people with kids and jobs and dogs get married was a threat to Western civilization. In the first case, I can understand how it's easy to unthinkingly absorb stereotypes. I just can't possibly imagine what it's like to be inside the mind of the second kind of person, any more than I can imagine what it's like to be a jellyfish or a doorknob.

But at least for five days, love won out over hate in San Francisco, and I'm glad to have been there to see part of it.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Today I more or less only worked on #4678, and I finally got stage1 to compile! Of course, it doesn't work yet. So far, I've changed the ty param list in a trait item to be a non-empty list, so that it's obvious which param is the self type parameter. That's the point of the issue, making the Self type in a trait just like any other type parameter (because that's what it is, and this gets rid of some needless code). But, I haven't updated resolve yet to resolve the Self type to the first ty param. At least my build's failing in the way I expect it to.

And, unbelievably, I'm not done with one-tuples either; I got the compiler to compile and the whole test suite to pass except... the one test case that I added for one-tuples, which fails to parse in the exact same way it did in the first place. sadtrombone.wav
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Over the weekend I'd been banging on #4183 without much insight. I tried to say everything I knew (which wasn't much) in comments on the issue; this morning I talked to Niko on IRC and as a result of what he said, I decided that #4678 should be fixed first.

The issue in 4183 had to do with the self type in a supertrait bound not getting the type parameter substitutions from the subtrait applied to it (in the code example there, the self type should be T but instead it was getting treated as unsubstituted self, causing an error message about T not matching self). #4678 says we should refactor the code so that the self type is no longer special, but rather, treated (internally to the compiler) as just another type parameter. That's not all that needs to be done -- also, we need to carry around each set of parameter substitutions in a chain of supertrait/subtrait relationships, otherwise T would still be unbound when checking the supertrait bound FuzzyEq<T>. But since #4678 needs to be done anyway, I think it'll be easier to do it first.

I couldn't quite stomach taking that on, though, so instead I went back to my branch where I was trying to finish removing macro code that generates code with structural records. There was a last bit of code in the pipes compiler did this, so I took a stab at removing it, which requires more advanced macrology than I've ever used in Rust before (which is to say, any macrology at all). I ran into a problem with, of all things, one-tuples. That's right, a tuple with only one field. Why would you ever want that? Well, there's a saying that whenever you ask that question in PL, the answer is macros, and in this case, it's macros. It doesn't seem like we parse tuple patterns with a single field properly, so I made a separate branch to just isolate that issue.

And that was Monday.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Well, maybe this meme is dying down, but I happened to re-read Emily's Trans 101, Upgoer Five Style and while it's good, I also couldn't resist writing my own version. Strangely enough, I felt like the limited vocabulary here helped me be clear, whereas when I was writing about my job, I felt too constrained by it in places (possibly because of having to circumlocute for technical terms, which was less of an issue here.)


Most people think that when a baby is very little, they can tell whether the baby is a boy or a girl. Also, they think that every baby is either a boy or a girl, never both.

They think this because they think that what a baby's between-the-legs looks like tells you whether the baby is a boy or a girl. But that's not true. Both boys and girls can have one kind of between-the-legs. And both boys and girls can have the other kind of between-the-legs. It's how you feel that makes you a boy or a girl, and babies can't talk to let other people know how they feel.

Also, there are more ways to feel than just boy or girl, and you can also feel any or all of those ways no matter what you have between your legs.

Some people think that everyone has a mark inside their cells that says they're a boy or that they're a girl. This, too, is wrong. These marks are real, but it's people who decided that one mark makes you a boy and the other mark makes you a girl. People are wrong sometimes.

Most people who get called a boy when they're a baby are boys, and most people who get called a girl when they're a baby are girls. It's harder for girls who got called boys, and boys who got called girls, and people who aren't boys or girls. There are two different ways in which it's harder.

First, some people have a picture of their body inside their brain that's of a body that looks and feels different than how the rest of their body is. You can't change that picture even by thinking very hard or getting help from another person. If you are this way, you have to change your body instead to make it match the picture in your brain.

Second, whether a person needs to change their body and does, or they need to change it but they can't, or they don't need to change it, many people aren't very nice to boys who don't look like they think a boy should look, or to girls who don't look like they think a girl should look, or when they can't decide if another person is a girl or a boy.

I'm in both the first and the second group. People thought I was a girl when I was a baby, but I was a boy. I didn't know this could even be true until I was much older. As soon as I found out that just because people thought I was a girl didn't mean I was one, I knew I wasn't a girl. After a while, I realized that I was a boy, and not someone who wasn't a girl or a boy. I was able to change my body to make it more like the picture that's built into my brain, so I'm much happier having a body now. And most people who see me realize I'm a boy without me having to tell them, which also makes me happy, because it was hard to explain to people who thought I was a girl that I was actually a boy.

It's harder for people who got called a boy when they were a baby but aren't boys, because lots of people are very afraid of people who they think have said no to being a boy. They think that someone else not wanting to look like a boy means being a boy won't be as fun for them. To deal with their fears about themselves, those people hurt other people. This gets in the way of the people who got called boys and aren't, who are just trying to live their lives.

You can make it better by believing people when they say that they're a girl, or that they're a boy, or that they're something else and not a girl or a boy. You can also make it better by telling people they are wrong when they make fun of others who they think are being boys wrong or being girls wrong.

Check it!
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Today, I overslept and missed a research talk by Tucker Taft, who was visiting today, on his language ParaSail. Oops!

...But fortunately, Tucker stayed around long enough to chat with the Rust team, and then was kind enough to give me a rehash of part of the talk one-on-one. ParaSail sounds like a pretty interesting language, with some things in common with Rust but more of a slant towards implicit parallelism rather than explicit. The compiler infers opportunities for parallelism in most cases, but the language also includes annotations that a particular loop in the code must be executable in parallel (meaning that if there are any ordering dependencies, it's a compile-time error). That's a nice idea, and reminds me a little of work I wanted to do in grad school (but didn't get to) on performance annotations.

ParaSail also has an ambitious precondition/postcondition language that's as powerful as the programming language itself (because it's the same language), which backs off to dynamic checks in cases where it's not possible to check a particular precondition within a reasonable amount of time statically. It'll be interesting to see if this eventually turns into a compiler that drops you into a theorem prover in cases where it can't prove your assertions automatically.

And as a result, didn't get much of anything done on Rust today, but I guess that's what the weekend is for!
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Triaged some bugs. It's now the case that I've reviewed open bugs 1-2000 in the past two weeks. That sector of the issue tracker is in pretty good order! Lots of the bugs that are still open are enhancements, the others mostly look pretty challenging. So it's not like we have a lot of old bugs we've rejected for no reason.

Following a FIXME, I tried to do what I thought would be a simple refactoring in resolve, and messed up trait method type parameters thoroughly. The usual.

Removed some more structural records, now that the Feb. 4 snapshot is finally live! But, it looks like I need yet another snapshot to remove the last of the structural records from the pipes macros. What's more, I don't understand the pipes compiler well enough to fix that, though I've been staring at it for quite some time today.

And that was today.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Over on Twitter, I wrote: 'Cis people have sexes, trans people have "gender identities"! Men are from Mars, women are from Venus!'

And a friend who is cis asked, in response, 'Suggestions for (gently?) correcting cis people who're under the impression that "gender identity" is what trans people prefer?'

One thing that I, and many other trans people say, is that if you're cis, and care about trans people, you should call out cissexism when you hear it: for example, if someone in your presence uses the t----- word (and is not a CAMAB trans person), or makes a joke whose humor is contingent on it being ridiculous or pathetic for CAMAB people to wear or do anything coded as feminine, you should inform them of your displeasure. There is no need to do so diplomatically or politely unless you think that is the most effective way to send a message to the offender, and anyone else present, that this behavior isn't acceptable. Rules don't have to be polite -- stop signs don't say "stop, please". As an ally to trans people, you assert a boundary when you say "it's not okay for you to use slurs around me." And there is no need to be particularly nice in stating that boundary.

To me, though, use of the term "gender identity" -- which is, in my opinion, almost always part of a stealth tactic to invalidate trans people's self-affirmed sexes and elevate cis people's identities to the status of "biological" -- falls into a different category from slurs and hateful jokes. First and foremost, some trans people do prefer the "gender identity" terminology; some trans people do say things like "my biological sex is female, but my gender identity is male". It makes me cringe to hear that, and when I feel like I can, I'll try to let people know that there are other ways of talking about our lives that are more honest and accurate.

But it's not a cis person's place to have that conversation with a trans person, and likewise, it's also not a cis person's place to claim they know what set of terminology is right for all trans people.

Here's what I suggest you do instead if you want to call out terms like "gender identity", and you're either cis, or being seen as cis: shift the focus to cisness, instead of transness. For example, you could ask: "Do you have a gender? Or do you have a gender identity? Do you feel you know what your sex is? If so, how would you feel if someone else told you they know what your sex is, and the sex you know you are is just a 'gender identity'?"

Even using the terms "cis" or "cissexual" bothers some people because they would just rather be called "normal"; if "cis" and trans" are adjectives of equal status, neither one marked as the "default" state, then it's almost as if being cis isn't any better than being trans. By getting cis people to understand that they are cis, that the way they relate to their body and to the labels they were coercively assigned at birth are not universal but are simply their subjective experiences (no better or more real than anyone else's subjective experiences), you can encourage other people cis people to step off the pedestal, and relate to trans people as equals rather than superiors. If you can name yourself as "cis", that's one step towards realizing that trans people are not flawed versions of yourself, but rather, people who are different from yourself, just as you are different from us.

In my opinion, "gender identity" serves a similar function to language that marks "trans" but leaves cisness unmarked. The language of "biological sex", being "born a man" or "born a woman" (which sounds painful for the individual giving birth), "chromosomes", and so on, all sound scientific, but in this case they're serving a decidedly political function: to lend legitimacy to the idea that people whose sex is different from the sex they were coercively assigned at birth do not exist. "Gender identity" makes us second-class and tells us we have to be second-class for science (and few things are considered more shameful among the middle class than rejecting science, or rejecting anything that can be framed as "science").

But not all trans people agree with me. So rather than trying to summarize what all trans people prefer (an exercise that's likely not to end well, any more than you could summarize what all cis people prefer), maybe focus on questions, instead of answers. "What do you mean by that?" can take you a long way. I think that's especially true when unpacking much of the language used to describe sex and gender, whose function is to subordinate some people politically and raise the status of others, rather than to describe reality.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Snapshot: still not quite done yet! Rarrr. Suddenly, an obscure problem appeared as the result of the combination of my snapshot and another commit, probably involving borrow checking. That commit got backed out, Niko's trying to figure out what the problem is, and the results are still building.

In the meantime I'm trying to make tuple-like struct constructors work cross-crate, which involves diving back into metadata reading and parsing. Which is my favorite part of the compiler. Oh, no, not "favorite", the other one...

Slow day. I also learned that if I want to get to the office on time for the weekly 9 AM Rust meeting, I should really leave home *more* than an hour before.
tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
I'm glad people got something out of my previous post! I would like to write more posts like that, but they take *a long time* to write. It's more important to me to make sure I post regularly about work than to post the highest-quality content than I can, so I usually stick with this "what did I do today?" format. Still, I'll try to occasionally write a longer post to mix it up (and you can always ask me a question about Rust, here or on Twitter; it just might inspire me).

The snapshot I tried to build over the weekend failed to build on Mac and Linux, and I'm glad I decided to just set that aside for the rest of the weekend, because I never would have figured out the problem on my own. The problem relates to two fun aspects of Rust: the compiler is self-hosting, and on Mac and Linux, we cross-compile so as to generate binaries for both 32-bit and 64-bit machines. That's why the build only failed on Mac and Linux.

Often when we're trying to remove a feature from the language (I was -- structural records), we'll add #[cfg(stage0)] attributes -- same for 1, 2, and/or 3 -- so as to have different versions of the same piece of code that gets used in different compiler "stages". Stage 0 is the snapshot, stage 1 is the result of building the compiler from a new source code tree using the snapshot, stage 2 is the same as stage 1 except building with the stage1 compiler (on the same source code tree) instead of the snapshot, and so on. (So it's *not* actually turtles all the way down.) Also, macros and staging interact in "fun" ways and so it's particularly hard to remove a feature when macros generate code that uses it. I was trying to change the Buffer type, which the pipes compiler (implemented as a syntax extension) uses, and I accidentally made the "old" version active in stage0 and stage1, and the new one only in stage2. What threw me off was that the FreeBSD and Windows snapshots built anyway -- but it turns out our build system interprets stages in some weird ways when we're cross-compiling.

Figuring that out was the painful part (though Graydon helped a lot) and then it was just a matter of following the type errors. Just another day of compiler janitor work (and I wouldn't want it any other way). Removing deprecated features is one of those things they don't (usually) teach you about in grad school.

As soon as the snapshot finishes building, I think that should allow me to banish structural records completely from the core library! (Which is only the first step to removing them completely; the compiler still uses them.) I actually submitted a pull request earlier that removes the last structural records from the standard library, which doesn't require the snapshot. Our shiny new build automation robot will, I hope, merge it in due course.

Profile

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Tim Chevalier

November 2021

S M T W T F S
 123456
78 910111213
14151617181920
21222324252627
282930    

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags