Justine’s APE [0] project is one of the few things to induce in me true, nostalgic, nerdful glee in the last few years.
At the same time, companies seem so quick to layoff that I question how I even grow to the point where I'd be trusted with such problems. Do I really just need to do a 2nd full time duty in the open source community to get that growth?
Obviously spending 20+ hours a week on interesting OSS is going to get you more interesting roles over time, and generally OSS stuff is way more fun because you can pick what interests you. But you have to decide if it's worth the cost - do you really want to spend 60 hours+ a week just doing coding / engineering? Maybe you do, but in that case you'd probably be doing it already.
It's ok to not be building some new thing in your off hours. That's a choice they made for their own reasons. Doing what you do is also a choice and both are valid.
- working on a medium-large repo size exercises more skills than just jumping into anything alone. Growth is my biggest factor for the next few years.
- OS introduces me to a community of passionate devs. Who can be anything from mentors to expand my horizons, to friends to future contacts.
- I'd choose to contribute to tools I would probably use for my own projects. So I can dig into repos early and know it intimately for the time I'd need to branch for my own project
- potential clout in certain communities can open other doors.
- Resume material is never bad if everything else falls through
It's not my end game but I think it'll help in many ways. And Personally I always had a certain respect for the OS community and want to give back, and hopefully pay if forward. .
I contribute to repos I use in my projects, but I’d never start with them before actually finding a use for them
And it would be a soul crushing world if I simply submitted to the fact that we're more connected than ever, but simultaneously I can't find literally anyone else to connect with without money being involved. I have at least a good decade in my heart left to fight that mentality.
> truly solving problems
By picking a problem you have a vested interest in, you'll get further than solving someone else's problems in which you don't
What a rude and profoundly dumb statement. Are all the ones who bust their arses out of necessity failures or do they simply want to endure pain? Caring for a handicapped child, parent, being trapped in a poor country, etc.
I'd be curious to know where most of you around here who put desires above all else are coming from.
A parent that cares for a disabled child is only a failure as long as he does not want to do it but has to. In this case he is not only a failure but a horrible person.
I volunteer to care for old people 1h per month and I do not consider this a burden or entrapping or nothing like that. In fact I've met my first wife like this.
> I volunteer to care for old people 1h per month
I'm sorry, it does not render what you're doing irrelevant, but the comparison is laughable.
Caring for a disabled children is a full time job. I can't imagine that most were hoping to be in that situation when they conceived. It doesn't prevent them from being good carers for the child they love. If you meet some of these parents, ask them. Then you can tell them they are horrible people because as opposed to them you voluntarily go to chat with an oldie for 1h a month.
Have some empathy.
I’ve seen the parents of severely disabled children. The daily work, financial cost, and social cost is immense. They don’t give up their children often out of duty and sympathy not because they ever wanted to live a life like that. They are burdened and entrapped and it’s not simply a matter of mindset.
Not even the disabled children would be keen to agree with you that their self-sacrificing parents are failures and horrible people if they feel they’ve been burdened and entrapped. THEY feel burdened and entrapped themselves. People in a bad situation can sympathize with people’s circumstances for what they are. They might resent the parent being open about their feelings, but not for having them at all.
As for why the 3rd world cab driver does not feel this way, a cab driver in the third world is often doing relatively well compared to their peers, they may have grown up in worse circumstances, and cab driving is something relatively easy to give up for a few years and then pick back up no worries. That’s not nessecarily true of the investment banker or the parent of the disabled child.
Your definition of what constitutes a "failure" doesn't have to be the same as someone else, and that's OK.
"For what it’s worth... it’s never too late, or in my case too early, to be whoever you want to be. There’s no time limit. Start whenever you want.... I hope you live a life you’re proud of, and if you’re not, I hope you have the courage to start over again."
My courage definitely wavers, but the stuff I'm "supposed" to do will hold me back if I try to what I want first. If I can't do that first, I'll at least set the breadcrumbs as I climb out of that pit.
It's a condition of certain kinds of life, to tolerate unbearable dissatisfaction. Many things have come from this drive, many astonishing people have shared it, and they'll never settle. They'll die still not 'done', their dreams unreached… because those dreams were able to scale, those stars remained beyond their reach.
Nah, not how it works.
[1] https://raw.githubusercontent.com/jart/cosmopolitan/1.0/ape/...
For the uniformed
> In the above one-liner, we've basically reconfigured the stock compiler on Linux so it outputs binaries that'll run on MacOS, Windows, FreeBSD, OpenBSD, and NetBSD too. They also boot from the BIOS. Please note this is intended for people who don't care about desktop GUIs, and just want stdio and sockets without devops toil
they also boot from the BIOS.... does this mean that I can achieve my dream of booting straight into a BBC BASIC emulator on bare metal(ish)?
Justine is a genius.
Older C compilers will let you get away with a lot of sins which a modern C compiler will (correctly) call you out for.
Under some very old C standards, maybe. But C99 requires that you at least declare a function before calling it.
Where is that written? Please quote the standard. My reading of ISO/IEC 9899:TC3 is that Foreword says (paraphrasing) "hey, we removed implicit int and implicit prototypes from the standard". So they simply stopped specifying it, but as far as I can tell, the standard says nothing about forbidding them. From my point of view, that means compilers are free to still implement implicit types as a compiler extension to the language, and everyone does, because that extension is needed in order to support the older c89 standard. It would only impact people who want to be able to claim their codebase is c99 standard compliant, because you can't do that if you depend on compiler extensions.
ISO/IEC 9899:TC3 [1] §6.5.1 ¶2: "An identifier is a primary expression, provided it has been declared as designating an object (in which case it is an lvalue) or a function (in which case it is a function designator)."
There's even a footnote to underscore this point: "79) Thus, an undeclared identifier is a violation of the syntax."
[1]: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
https://en.m.wikipedia.org/wiki/Forward_declaration
https://en.m.wikipedia.org/wiki/Pascal_(programming_language...
https://en.m.wikipedia.org/wiki/Object_Pascal
https://www.thedelphigeek.com/2017/03/forward-record-declara...
There is no such requirement of a declaration before first call in Java for example?
Kind of like how the JavaScript dudes all use this ".ts" stuff now for convenience that processes into ".js"
let x: number = 6;
You should instead allow the compiler to infer where it can and do
let x = 6;
Inference doesn't work across function calls like it does (did?) in Flow, which is a good thing, so those always need to be typed.
If you wanted the type of x to be 6 instead of number, you would use
let x = 6 as const;
extern int id();
The empty parentheses meant it could take any number of arguments, since it was declared in the traditional style, where the argument types weren't specified first.This implicit declaration meant that if it was later defined in the same file as returning a type other than int, the compiler wasn't permitted to go back up in the file and treat the function call as though it returned a type other than int.
This requirement was removed in C99, but in practice, compilers kept doing it for backwards compatibility, even when not invoked in C90 mode.
You do have analyses like ctags. In theory the compiler could use ctags to find definitions in source code. My experience is ctags can get confused. It's possible in a set of files to have multiple implementations of a function and ctags can't tell which one is used. And I see cases where it can't find definitions.
Personally I'd be happy if the compiler tried to find a missing definition using ctags and issued a warning.
I have wondered if adding funct, public, private keywords to the language might allow the compiler to reliably find function and stuct definitions in source files.
That's not necessarily true. It's possible that the symbol is a function pointer; calling a function pointer requires slightly different code generation. Compare the generated code between:
void fn(void);
void call_fn(void) { fn(); }
and void (*fn_ptr)(void);
void call_fn_ptr(void) { fn_ptr(); }
In practice, it's probably a function, and that's what the compiler assumes if there's no declaration to go off of. But we all know what happens when you make assumptions.you mean the linker will throw an error. The linker is trying to link together the "references" be they forward or backward, that the compiler has created, and the compiler needs to have generated the right references, round peg round hole, square peg square hole.
You don't want your linker throwing errors, it doesn't have the context the compiler does; and you don't want to turn the linker into ChatGPT that can converse with you about your source code, just use the C version of forward references which are not particularly forward, they just say "I don't know where this is defined, it's just not defined here, but we know it's a square peg"
For example, there are architectures where space is tight (embedded for example) and nearby things can be called more efficiently than far away things, so the compiler needs to generate as many near calls as it can, falling back to far away when it has to. It doesn't know in advance how far away things are going to be, but it might uncover plenty of near things as it goes. Square pegs, round pegs.
when you recompile your project code, the library code, is not necessarily around. When other people recompile their library code, your project code isn't around. What's the size of what's being put on the stack? Still gotta get the square/round pegs right.
Win32 C code from way back.
Heh.
if(*(Ptr = argv[i]) == '-') {
Older C compilers did let you get away with more, like using integers as pointers, and dereferencing pointers as though they were struct pointers when they aren't. But I don't see that in this code.It's not even a good idea to do that on modern computers, because implicitly declared functions do type promotions from float to double and char/short to int, and on the System V ABI, it has to pass in the number of floating point arguments there are in register eax.
A low bar, really :-P
In older C compilers (maybe pre-ANSI, or later, can't remember), you could literally write i[a] instead of a[i], where a was an array and i was an int, and it would work equivalently, i.e. no compiler error, and give the same result as a[i]. This was because a was the address of the start of the array, and i was an offset, so a[i] actually meant *(a + i), which, by the commutative property of arithmetic, was equivalent to *(i + a), which was equivalent to i[a].
I had read this in some C book, maybe K&R or the Waite Group C Microsoft Bible.
Never forgot it, because it was counter-intuitive, unless you knew the above reason.
And tried it out in one or more C compilers at that approximate period, and it worked as stated.
https://godbolt.org/z/37Kv44o1b
> I had read this in some C book, maybe K&R or the Waite Group C Microsoft Bible.
I haven't read the Microsoft C Bible, but it does say this in K&R while explaining pointers.
Wow, good to know.
>but it does say this in K&R
Then that must be where I had read it.
Cargo pulled in something like 105 dependencies to build it.
Although, as an apples to apples comparison, it does only have 2 use statements.
Here is a http health check in 19 lines using only the rust standard library.
There’s a happy medium to be had.
I’d also disagree this is not at all a language problem - I think it’s both, in that the language has moved an awful lot of core functionality into the crate ecosystem, where there are a bewildering array of options for almost any need. The resulting explosion in the dependency graph is an entirely foreseeable consequence — partially of that language design decision and partially due to the “npm culture” (for lack of a better description.)
The list goes on. While I'm not a Rust developer, there's probably hundreds of libraries because the problem is structured into a lot of small parts, and frameworks are expected to be able to satisfy the functionality you expect without needing to bypass it.
(The signal_hook crate even contains documentation on those pitfalls. https://docs.rs/signal-hook-registry/1.4.1/signal_hook_regis...)
I mean sure, reinvent the wheel. But it might do good to at least have an inkling what those 105 dependencies for your http listener did.
I ended up going with sigwaitinfo since the attempts you likely saw on matrix which is perfect for my application that will only ever run on modern linux kernels.
Combining that with the stdlib health check above and we end up with a dead simple health checking signal handling service pattern that works well and easy to confirm is free of supply chain attacks.
:)
https://en.m.wikipedia.org/wiki/No_true_Scotsman
Not sure if that's a good analogy, but put it out there, to see what people say.