Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Interview with Douglas Crockford (evrone.com)
97 points by lizziedevoir on July 19, 2022 | hide | past | favorite | 99 comments


I thought this part was rather interesting:

> Evrone: You spread the idea that developers should read each other's code regularly…

> Douglas: In filmmaking, there is a time in the morning called "dailies", when the previous day's footage is examined. It looks like everyone is just sitting around watching movies and wasting time, but it is critically important in finding problems early and assuring the quality of the product. I believe that we should do the same thing in programming. We have a time every morning when the team gets together and reviews all of the code and designs that were developed the previous day.


We tried this in a team a few years ago, and the problem we faced was developers literally falling asleep during readings. We found that the Team wasn't really engaging with the process and instead just tuned out until it was their turn.

That doesn't mean I think Crockford's "Dailies" model is a poor one, it's just one issue to be aware of. Though I often find the same in Scrum teams. Folks aren't listening, they're just waiting for their turn to speak.


> literally falling asleep during readings

Dailies in film is watching not quite the final product, but still an output of the process. Maybe the issue was reading code as a team (that's code review/PR) rather than reviewing the output of the code? I think Dailies as a metaphor to me sounds like a call for more regular QA/UAT style review sessions as team. (This metaphor is new to me, but regular "use the product as a team" sessions might be quite useful, just maybe not every day.)


Though he doesn't mention it in this video, I have seen Crockford promoting the 'Dailies' idea in talks before - and he does promote it as a replacement for code review and stand up.

One hour, every morning, where the entire Team reads the code written the previous day and offers feedback. Juniors learn from seeing real-world code presented and explained, Seniors get peer review, more eyes means fewer bugs, etc.

It didn't work for my Team, but I would be interested in trying it again in future.


This has been common in the scrum ceremonies I've participated in in most of my career. The standup is primarily for keeping your manager up to date on how things are going with your estimates and maybe for asking for help from a coworker with a blocking issue.

I think what Crockford outlines here would be fantastic if it worked. Multiparty code review.


The reason it works for movie production teams is that they don’t watch dailies most working days of their career.

The film shoot is a special high-intensity time. You may spend months and months in pre-production, but the actual shoot might only be 20-30 days (on a lower-end production). Every day needs to count. If you can learn from the previous day and improve, it makes a real difference near the end of the shoot when you’ll have much more freedom to experiment.

In contrast, software engineering is more of a uniform slog. Back when software shipped in physical boxes, there used to be a marked difference between the planning, development and testing phases, but that’s gone. At many companies it’s just a grind of tiny features and endless tickets. Hard to get excited about the “dailies” for that.


Plus, if you miss a mistake in a shoot it will be expensive to fix after shooting wraps, if not impossible. Bugs might get more expensive to fix over time, but most don't, really. Not like that—not with such a very-near-future cliff after which they get far more expensive. And I'm not sure how many more you'd catch doing daily team reviews versus less-frequent targeted code reviews, anyway. The practice sure sounds brain-meltingly dull, to me, and with little benefit.


If it feels that way I think your scrum master or entire team is doing a poor job. It shouldn't feel that way if you want it to work.


That's how it's felt at literally every software job I've had that has done the "standup" thing.


Same here. I've never experienced a place where standups added value (at least from my perspective.). Quite the opposite actually.


Same. I don't hate them (they last at most 10 min.), but as someone who has been working for more than 12 years in the industry I think managers/teams do daily stand-ups because of cargo cult.


It's a really boring 10 minutes though and it happens everyday. And it translates to more than 10 minutes of wasted time because of the context switch (and the added drudgery that can affect morale)


Same here. I went looking for a non-standup job last month.. I didn't come across any.


My current company has one once a week which is tolerable. We're hiring, especially for FE developers if you're interested.


Sounds like a problem with the team more with the process. If they don't care, they wont care.


> If they don't care, they wont care.

We need to accommodate human nature, not change human nature to accommodate corporate requirements. Its irrational to expect a group to rally passionately around every available task. Robotic.


The good question is how to hire people that will care, and whether or not it can be incorporated into a culture.


Let's hire people good at programming and let's leave the fluff behind.


After many years, defining "good at programming" is hard. I would say, reading your code is part of that. I used to read all the code that got checked-in for one of my large projects.

The other part is that you can also grow people into being good. This is one of the more important roles of big-tech where college grads come in as n00bs and become engineers.


> Folks aren't listening, they're just waiting for their turn to speak.

That statement works in so many contexts


Yeah, I'm curious how common this is. If anyone has done it/is doing it successfully, could you share more about the approach? It sounds valuable in theory but it also sounds like a ton of time during which people can half-listen and say "Sure sure, looks good", especially on a larger team.


I tried it with my team about 4-5 years ago and found it, while useful, to be too much overhead for the benefit it provides, especially when compared to normal ad-hoc code review.

I will do something similar as part of big product releases though: I'll get the team together and we'll do a once over walk through over everything end to end. Normally this produces about an additional sprint (two weeks) of work ahead of the launch as you uncover problems and people see things with fresh eyes. So make sure to build that time into your schedule.


If you hear advice that’s not prefixed with “we started using it X ago and works great…” - be sceptical as default.


A couple teams ago we did frequent pair programming and routine code reviews. We discovered both practices were very useful in some contexts, but a waste of time in others. For instance, do you really need to review each others semi-robotically-generated accessors or other simple code? Probably not (though checking such code is in line with previously established architectural guidelines is a good idea.) But there are some parts of the codebase where it is extremely useful. Figuring out which is which is sometimes more of an art than a science.

(As an aside, I think I understand a bit more about Lisp macros after contemplating this... Properly applied macros and DRYness allow you to elimiate much of your "simple" boilerplate, so you're left with beefier chunks of functionality. Like everything else, though, YMMV.)


Plus there's the fact that film casts and crews have a work day that's quite a bit longer than a programmer's typical work day. We have already enough problems with crunch; do we want to make 10-12 hour workdays the norm? Because that's what will happen if you want to maintain current development velocity.


Finding problems earlier increases velocity, so I would expect the opposite. If people are spending all 8 hours coding it is unlikely they are producing good code.


Is the only difference between this and a standard code-review process that the whole team participates in each change?


Interesting. I had no idea he had transitioned from promoting Javascript's good parts to calling for its retirement.

I started to get a bad feeling when the class keyword became popular, but all of the old good parts are still there.


I vastly prefer functional programming to OOP. But I find my use of `class` in JS increasing for two reasons orthogonal to the paradigm distinction:

1. Particularly in pure JS projects which either haven’t yet or won’t migrate to TypeScript, classes are an excellent way to define data types. They needn’t be stateful, they can be used just like POJOs in otherwise pure functional code. But their shape is clear (or can/should be), and can be used as both types and runtime references without a lot of ceremony.

2. Classes, when they have a clear shape, are great for performance-sensitive code. POJOs can achieve this, but it’s frequently all too easy for their shape to evolve as a codebase is in maintenance. And that can cause hard to find performance regressions.


Using runtime classes can also be handy if you're willing to use `instanceof` (or the speedier constructor comparison) to disambiguate between types, such as when you want to branch on Left/Right in an Either, or None/Just in a Maybe, or Error/Success in a Result, etc.


I also tend to prefer functional programming to OOP in JS, but there's a massive legacy of OOP in JS. The `class` syntax really is just syntactic sugar for classic IIFE-wrapped `.prototype.` JS OOP. You can pass modern classes to ancient JS OOP libraries like for instance Dojo and there's sometimes few things quite as satisfying when upgrading legacy code as replacing the classic legacy spaghetti Dojo class definition IIFE with a much simpler `class SomeLegacyWidget extends DojoWidget {}`. Almost no one even needs to know what an IIFE even is or stands for today. It's great.

That `class` syntax works in all the modern browsers today, no Typescript transpile or Babel plugin or "polyfill" needed.

(Dojo comes to mind because of doing code on current ArcGIS-related projects that are still stuck in the mines of ancient Dojo versions, IIFE "classes", and AMD wrappers. Still great to have Typescript generate the AMD wrappers for you from modern ES2015 module syntax, but `class` and even `await/async` you can get for "free" in modern browsers and are huge clarifying changes to legacy Dojo work.)


Immutability in JS is painful and tedious, how can you enjoy write functional code in JS?


I don’t find it painful or tedious.

- Constructing flat POJO values is trivial (spread + define any changed properties).

- Immutable array operations are fairly robust, albeit not as expressive as some may want. Getting comfortable with reduce improves this dramatically.

- Map/Set constructors accept instances to create new values.

- Class instances used as value types are simple to derive, assuming their constructors accept objects in their shape. If they have a consistent shape, deeply nested clones with consistent descendant classes are equally trivial.

- Iterators could play nicer with other native interfaces, but they’re pretty handy even so. Custom iterators are exceedingly handy for shuttling data between types.

- More expressive operations over sequence-like structures is as simple as operating on iterators. This will feel more reasonable if you favor Map over POJO for mapped types.

- Imperative stateful functions are admittedly a pain, but wrapping them in functions which return meaningful state you’ll need later is pretty straightforward.

- Really though, starting from a functional perspective just makes these details a non-issue. If your primary tool is a pure function, any gap in these interfaces can be filled by writing a function and calling it rather than the imperative code.

If some or all of that sounds like it’s a performance nightmare… most of the time it isn’t. But if you have a hot loop where copy on write is a meaningful bottleneck:

- You can take inspiration from Clojure or other functional languages with persistent data structures. There are a ton of libraries.

- You can take inspiration from Clojure or other functional languages with a concept like transients, and isolate your mutable code in a function body. This doesn’t even need a library, it’s just bailing to the imperative code the language ostensibly wants you to write in the first place, and being thoughtful about how it’s encapsulated.

What I do find painful and tedious is trying to follow stateful imperative code which hasn’t been subjected to intense discipline. This is true regardless of the language. It’s true whether the code is “object oriented” or not.


> You can take inspiration from Clojure

Famously Ramdajs on its front page has: we're not porting over all of the Clojure functions. To slow down this direction, for good reasons perhaps. Still its very visible that FP idioms travel nicely between langs/platforms.


Thanks

Your list sums up why I find it tedious ;), since you mention Clojure, in Clojure one doesn't have to think about those things and go through hoops(except for when doing Java interop). Unfortunately I don't think Clojurescript is worth the hassle(or even immutablejs or immer) and just prefer writing JS and applying your list.

Functional programming languages spoil you in this regard.


> Your list sums up why I find it tedious ;)

Weird!

> Unfortunately I don't think Clojurescript is worth the hassle(or even immutablejs or immer) and just prefer writing JS and applying your list.

Seems like we agree actually?


Seconding this


> I started to get a bad feeling when the class keyword became popular, but all of the old good parts are still there.

I actually like many of the new parts - the class keyword being a notable exception. The other (much much milder) exception is async/await syntax - I love Promises but the async/await sugar on top of it this seems a little too much like magic. At the end of the day, they're still just Promises, just weirdly abstracted (just as classes are still just prototypes, just obscured so they look like something they're not).

The odd thing imo about the class keyword is it doesn't even seem to "fit" with the direction of may of the other new changes. E.g. arrow-functions are a very un-classy simplified functional form (no this re-assignment). This is very evident in the direction of many frameworks - e.g. React quickly moved to using classes (extends React.Component) and then quickly moved away from that convention (function components) as if realising their mistake.


I think async/await could perhaps have been better used as more general threading primitives to shift the language more toward multithreading. I do like them in comparison to raw promises though.


> I do like them in comparison to raw promises though.

Promises can get a little unwieldy raw - working on making that easier is a noble goal. But I'm never a fan of systems that actively obscure how something works. We now have plenty of people throwing asyncs and awaits around their code without a clue about how Promises work. It's significantly easier to learn how specific control flows work while writing raw Promises.


Yeah, but the problem is that people will still use the new parts too.

I never really liked any of the JS's attempts at OOP, be it the original prototype-based or the newer class-based, but I think that people were sufficiently confused enough by the prototype system that most people didn't bother with it. The class stuff is more approachable, and for some people that can sort of be viewed as a bad thing.


The newer class based IS the original prototype based. Class is literally just syntactic sugar on top of prototype inheritance. It was just added to help people coming from true OOP languages to feel comfortable. Notice, for instance, in Java the class acts as a blueprint for the object. You can’t have the object without the class. Not so in JS. The class is just window dressing and is not required at all.


Most of this seems reasonably on point except for

> true OOP languages

Specifically the Java used as a example isn't exactly a "true OOP language" either; in a sense it's actually a very leaky imperative VM with implementation details like non-object Primitive Data Types and very visible and prominent imperative flow control structures.

Javascript is much closer to an actual "true OOP language" as, unless you're dealing with bad/naive bindings to other stuff in C, it's very hard to even get a handle of a non-object.


Sure, but in practice most people ignore the prototypal features, especially if they're using the "class" keyword, so it may as well not be prototypal. Which is good, because the distinctly prototypal pieces are usually bad behaviors to rely on. The wrong kind of magic.


Douglas Crockfords' "JavaScript the good parts, took me from being a mediocre JS developer to truly understanding the language's inner-workings. Highly recommend.


Why aren't the links in the body text... links? Really screws with accessibility.


It seems that they only work properly if JavaScript is enabled...


…which is only fitting.


Because they are not actually links (as in `<a>` elements) but they are `<i>` elements (italics) that are formatted differently and also opens a new tab when you click on it.

But they are not common links, which is stupid. Hovering the "link" doesn't display the URL in the browser, right-clicking doesn't understand it's a link (because it's not), you can't open it in a new window as the creator of these "links" didn't consider that behavior (shift+click) and they are not accessible in the least.

TLDR: author re-implemented their own links, with more drawbacks than they could imagine


They are for me, chrome desktop.


Totally agree. Very annoying.


I am surprised he doesn’t like the more recent additions to JavaScript. I liked ES6 features quite a lot.


"The best thing we can do today to JavaScript is to retire it."

I think that's a pretty interesting statement from somebody like Douglas Crockford. Not disagreeing; but still ...

I think there are two ways of looking at recent changes in Javascript. Either it's progress or it's just not enough progress. I think what he is saying here is that there it has too much baggage and that there are newer and more interesting languages now. That's not such a strange thing to say for somebody that has been involved with trying to create new languages.

My personal view is that browser Javascript is mostly a compilation target these days, including for Javascript itself, and that we now have a better compilation target in the form of WASM that is less awkward to target for a lot of languages as well. The question is what languages people will be using in the next years that target that. I'd say there are some interesting alternatives to choose from already and there are likely to be more in the next few years.


Javascript has GC and tail calls, and I don't think WASM is getting either anytime soon.


The experimental Kotlin WASM uses some experimental GC related flags in chrome. That stuff is working right now and will no doubt stop being experimental at some point. Tail calls might take a bit longer but there are probably people working on that too. But there are probably ways around that. WASM is already useful today and will incrementally get more useful over the next few years.


I'm not sure about other engines but V8 the most popular JS engine does not implement tail calls.


Isn't not efficiently implementing tail calls a current JS standard (in that implementing them means your implementation is technically broken) specifically to prevent software from relying on that optimization?


Someone should tell Ecma then: https://tc39.es/ecma262/multipage/ecmascript-language-functi...

I was wrong, though, tail calls are in ES14, and eliminating them is probably not implemented anywhere yet.

Edit: Wrong again, tail-call optimizations are in WebKit; iOS has had them since iOS 12 according to this: https://kangax.github.io/compat-table/es6/#test-proper_tail_...


He has said that a good language avoids exposing the programmer to choices that they can make incorrectly. He probably sees some added features in Javascript as creating such choices.


ES6 is what makes JS bearable to write modern day. Totally don't understand his point here. Who wants endless nested promise chains?


I can't speak for Crockford obviously, but my guess is that all these extra features come at the cost of making the language "bigger". I think part of the reason people liked JS in the early days was (at least if you avoided the attempt at OOP) how simple it was. You basically only had a few core types that were flexible enough to do what you needed, you worked with simple functions that worked on those core types, and you built simple abstractions on top of that.

Obviously this can be a blessing or a curse depending on who's writing the code; it's not terribly hard to write yourself a spaghetti mess of chaos in JS. Callbacks lead to a mess of nested lambdas, promises are better but still a bit clunky, and trying to work within the "few core types" led to the famous "wat" video [1], so these things come in tradeoffs.

Still, I see where Crockford is coming from (at least if I understand his point correctly). My interview language of choice is JavaScript, and I rarely use anything introduced from 2015 or later (except the shorthand function syntax). I like that the core language has basically no bureaucracy, and you can focus on just writing code.

[1] https://www.destroyallsoftware.com/talks/wat


> Who wants endless nested promise chains?

One of the things Promises solves is nesting. If you're nesting them, you're doing it wrong.

(I don't mean "never nest them"... but if you find you're nesting them, see if you can refactor to "all()" them or similar)


You "should" never nest them, if you create a new Promise inside a .then() callback, immediately return it and move to a new .then() callback in the chain. Promises were built to flatten.

The hard part, of course, is threading complex flows of variables through your .then() callbacks where later Promise calls need a previous variable or three, and that's when a lot of people give up and just resort to deeper nesting. That's what async/await does the best at solving: capturing variables automatically in a simple state machine written like classic imperative code versus manually trying to thread state through callback closures and complex return types.


> Who wants endless nested promise chains?

Believe it or not, you can actually structure things so it's "flat" looking without async/await (or even without Promises for that matter, but Promises solve other problems too).

Just because someone argues against something like async/await, doesn't mean they want the thing async/await is supposed to address.


I've always felt there's a disconnect between two groups of people, those who use a language in their day-to-day work and those who approach it more as an object of study (i.e. academics or hobbyists). The latter view bloat as a bad thing, while it's not the biggest concern for the former (who have more pressing problems!). So for Crockford an expanding language definition is catastrophic, but for people writing web apps, if 1 new feature out of 10 very useful then it's still a huge win.


I'm not a academic nor hobbyist but work professionally with JavaScript for more than 10 years.

I'm also "against" the constant syntactic sugar that gets added with little to no benefits, just leading to JavaScript having a large syntax.

Why introduce "classes" which are just sugar on top of existing syntax? Many examples just like this, where sometimes it feels like JavaScript has changes just to have changes.

Although I'm not gonna complain too much, many of the new features are more than just syntactic sugar and makes my life a lot easier. I just wish they were slightly more conservative I guess.


To take your argument to the extreme, why have for loops, when then are syntatic sugar over while loops? I'm generally a fan of syntatic sugar in a language if it's purpose is to simplify what's already there; but it is a balance between developer productivity and ease-of-use. I once saw javscript described as 'pithy', becuase of it's small syntatical footprint, that's probably not true so much now.


I believe Crockford said in a talk [1] that he was going to stop writing loops when tail-call elimination is supported everywhere.

Also, avoiding the for loop in JS might be a good idea because of how easy it is to shoot yourself in the foot with "for (x in stuff) ..." creating a global variable (when you accidentally leave out "var").

[1] Probably this one? https://www.youtube.com/watch?v=XFTOG895C7c


Indeed. Just as with real sugar, a little syntactic sugar is great, but too much is icky.


I agree with you, but you also agree with me, I think.

You said that, despite the bloat, you won't complain too much because some features make your life easier. That's precisely what I was saying!


my feeling was that Crockford’s ‘…good parts’ was intensely pragmatic. About as far away from the academic approach you’re describing as i can imagine. A bigger, multi paradigm language makes it harder to read other peoples code as the chances are higher that they’re employing a different paradigm or alter a different idiom, a clear maintenance burden.


Pragmistism literally means utility for problem solving. Who do you know solves problems using a Crockford-style subset of language features?

Note that, no where did I argue that bloat is good. I only said that it was tolerable given that some new features are useful. Maintenance burden is a real problem, but is still tolerated in practice.

I don't agree that subsetting a language is far from an academic approach. In fact this is what pretty much every PLT class does in order to make reasoning about language definitions easier.


Identifying that subset of the language was paradigm shift in JS development. around 2008 when the good parts came out i don’t know any serious JS developers who didn’t take on board many of its lessons. examples: avoiding ‘this’, understanding the value of functions as first class citizens, understanding closures. these weren’t unique to crockford but by presenting them in an accesible plain spoken way he moved the state of the language forward.

i do agree that there’s a need to weigh the value of new features vs bloat but id say 1 good feature in ten is pretty poor odds.

another example of crockfords pragmatism is JSON which for all its flaws has been a real boon.

edit: un-auto correcting “crockpot” :D


Interesting points, thank you! JSON is a great example, I understand what you meant now.

That being said, I really wish JSON had comments :P


And those new features are usually new/different/“better” ways of doing what you could already do in the language. You can totally use JS without using any of the ES6+ syntax.


Do you do this personally, or do you use ES6+?


The ES6 additions were great. It's the ones post ES6 (like private fields) which are becoming increasingly questionable.


For anyone coming back to this, I just wrote a small proposal to define JSON5 duplicate object name behavior. I'd love any support on the issue:

https://github.com/json5/json5-spec/issues/38


Nice one! Is it just me though, or is he becoming quite repetitive in what he says in interviews these days, e.g. retire Javascript?


Not sure the format helped. No follow-up questions, no real thread of discussion. If you are faced with an interview like that (and for people interviewed regularly I imagine there are tons of interviews like that), why deviate from your stock answers?


One of the answers contains a link ("You can see proof [here]") and another references a previous answer in a way you would only do in writing ("See my previous answer")

Fairly sure it wasn't really an "interview", and just an emailed response to a list of questions.


Eval is not evil.


If misused it is. And it is very very easy to misuse.


On the other hand, what is not "evil" when misused?


Anything can be used for evil if you try, some things you have to make an effort to fight or they'll invite (or actively cause) evil by default, there is quite a difference there.


Evil.


> But since then, there has been strong interest in further bloating the language instead of making it better. So JavaScript, like the other dinosaur languages, has become a barrier to progress.

Strange that he says this, because the original "Good Parts" principle is that you can use the "good" subset of the language.

No matter how many new features they add, that same "good" subset is still there ready to use due to backward compatibility.


I always assumed the creator of JSON was named Jason…


Retire all the things. What makes this industry so…cyberpunk, is that nothing entirely goes away.

Linux is probably the last time something was really built from scratch. Most commercial software in use today is dependent on code written in the 80’s and 90’s.

So, yes, there is a need for new software to match the new paradigms, but the task of starting from scratch is colossal.


> Linux is probably the last time something was really built from scratch.

Linux was started in 1991. Windows NT (whence Windows XP and modern Windows versions derive from) dates from at least 1993 (I don't know when the code internally started, but the first release was 1993).

For browsers, Firefox source code originates from Netscape 6, which was a rewrite from scratch and shared little to no code with Netscape 4 or earlier. This rewrite happened in 1998. IE dates from 1994, per Wikipedia. KHTML, whence Safari and Chrome ultimately derive, is itself from 2000.

Let's talk about programming languages. Java dates its early work to 1991. .NET Framework is the late 90s (Wikipedia is exceptionally poor with dates here). The LLVM framework dates to 2000 in the earliest. Accelerator programming languages like CUDA and OpenCL are deep into the 2000s in their genesis, and the development of more fully heterogeneous programming languages obviously postdates that.

That's a lot of significant projects that date way later than Linux.


Maybe so for Windows NT, but Linux 1.0 was released in 94. It feels strange because I was on the mailing list when Linus announced his project, and I had just gotten out of college when 1.0 became official.

And yes as well on anything serious that deals with modern CPU architectures.

But my point was that the old stuff has not been replaced, it’s still out there and often times you don’t have to dig much to find it. Particularly at the OS level, in memory management, multithreading, networking stacks and hardware drivers.

So the jungle simply becomes more diverse and nothing ever gets retired.

Lord, I came across a jumble of Perl code just a few weeks ago.


Im the article there is a Google Trends of JSON vs XML: https://trends.google.com/trends/explore?date=all&geo=US&q=x...

I'm curious about what caused the sudden down peak?


JSON is much easier to parse with your eyes and there isn't much of a performance difference anymore..


With SIMD JSON parsing, I'd be very surprised if JSON weren't MUCH faster to use than XML. Smaller payloads also translate into less time over the wire too.


Can someone explain his last two books? Is that satire? Just a prank?


"JavaScript must die. Long live JavaScript."


JSON isn't the be all and end all data format. It's full of ambiguities and has pointless, misleading cruft like filtering "unprintable characters". Plain text is also a dead end and misconception contra UN*X hippies.


XML?


God douglas crockford is such a cool guy. Douglas Crockford invented the internet, distributed systems, JSON, dec64, Javascript, E, for loops, and mathematics. Obviously whatever he says goes. When he speaks in an interview a link appears. But in all serious it is time to move away from Javascript. Pretty much every professional javascript developer I worked with in my career doesn't even understand browser Javascript from Nodejs, Typescript, ES6, ES5, imports/exports, commonjs, JSX, and OMG the list goes on... like... forever. Put a fork in it...




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: