Hacker Newsnew | past | comments | ask | show | jobs | submit | AbsoluteCabbage's commentslogin

> Nintendo proved again that gameplay and art direction matter more than anything

More like- Nintendo proved that in spite of barely listening to the fan base over literal decades, a solid brand will still get sales with just bleh content.

They barely caught onto the open world concept and sandbox - and it took years and years.


C is making a big comeback. More and more people are waking up to what utter garbage the modern frameworks and languages are.


Where is it making a comeback? Are people writing web and mobile apps in C?


There are likely dozens of others out there that can lay claim to the same. What specifically do you define as the innovation behind this “invention”?


I'm sure that many can make the same claim. In the 1980's, I was an operating systems architect working at IBM. I thought up many interesting (to me) innovations while working on the first couple of releases of the AIX on the IBM POWER hardware. It was a great job and I learned a lot doing it. I got to work with some really brilliant developers and computer scientists (a number from IBM Research).

One project I was responsible for was the development of a distributed file system for AIX. The goal was a distributed file system that addressed some of the weaknesses found in other distributed file systems at the time. Our chief competitor was Sun's NFS distributed file system. NFS was a really nice design. It was well integrated into the operating system and quite reliable because it utilized a (mostly) stateless server. This had a number of performance and security implications along with some file system semantics over NFS that didn't match local file system semantics. We wanted to introduce state for the server to address these issues and thought of a number of complex protocols to manage it in the presence of unreliable clients. That's when I thought up the idea of making the clients keep their own state to be restored when they reconnected to the server. I protected this state from manipulation by the client by encrypting it. I didn't call them cookies, I called them tokens.

This design was patented by IBM and I was one of the two inventors on the patent. This patent was owned by IBM and years later they gave a special award for this patent because it decided that it was one of IBM's most important patents. (They wouldn't have done this unless the patent had held up to scrutiny or legal challenges). Unfortunately, by that time I had already left IBM to start my own company--I was at the top of my game and had confidence that I could create a software product of some kind that would be successful--so I missed out on the financial award for the patent. By then, I was at my new company and already in competition with IBM.

By now, the patent should be long expired. Interestingly, IBM ended up buying my company around seven years after I and a partner started it.

I was very aware of the academic literature and industrial practice during this time so I do believe that my invention does reflect original work that ended up with a very significant impact.

From a more personal perspective, the invention didn't financially benefit me. The work that I did at my company own was more creative, inventive, technically impactful, and financially important to me. For example, Austin Ventures has indicated that my company was the start of Austin becoming an important high-tech location, but none of that was related to the cookie.


What was your company?


I'm going to put my guess in as Tivoli.


Yes


i did a consulting gig rolling out Tivoli at Dell in the mid-90s, i think pre-IBM merger! loved the software, hated the [flat] network Dell had in Round Rock at the time! thanks for your detailed comment. love reading tech history stories.


At least now people will start to focus on how bloated and slow software has become in the meantime. And stop referring to it as “tech”.


I (unfortunately) doubt it. I think the reality with our current situation is that only hobbyists and open source people care enough about that to do anything about it. Everyone else is doing Scrum so hard that they can't think of much outside the current sprint, and any "pre-mature optimization" is evil and must be avoided. The result will be more of the same bloat. Competition won't help because everybody is using the same bloated foundations and nobody will invest more than a few days in the foundation because it's not "product work."

The best we can hope for I think is that open source will create frameworks/foundations on top of which people can then try to build. Elixir Phoenix has been that to some extent, basically taking the rails philosophy but making it super light and fast (my Phoenix APIs run with 40MiB of memory and response times ~1ms). Maybe those sorts of advancements can save us, but I can't think of a way to address the browser that way and realistically right now the browser is a huge area of the bloat. A ton of code that runs in the browser is terribly optimized, but even the base is quite big.


That's exponential era practices. But we're hitting the top of the S curve. Believing that exponential era practices will continue indefinitely into the coming linear/level era is as naive as believing exponential growth continues forever.

The real question is what happens first: change in software to adapt to slow growing compute or change in architecture to revitalize Moore's law.


Oh, I don't think it's quite that grim. When development teams can no longer easily spend their way out of their inefficient code, being able to write high performance code becomes a competitive advantage. I'd even go so far as to say that individual developers looking to get ahead in their careers should pay less attention to flashy tech fads and more at foundational stuff like how to diagnose performance problems and write efficient code.


> Everyone else is doing Scrum so hard that they can't think of much outside the current sprint

This is a gross oversimplification. While there’re inefficiencies and process abuses, this doesn’t mean nobody cares about speed and resources. It might look that way to purists who’re focused only on tech part of the businesses.


Processors used to spend most of their time sorting, after a period of wasteful bullshit they may return to hotspot's dominating again in the form of AI inference.


Won't we have dedicated analog/optical/whatever inference accelerators by that point as well?


Compute time is cheaper than man hours.


Its not like biological creatures are highly optimized.


Eh, for the amount of work your brain accomplishes, it is insanely hyper optimized at around 20 watts. We don't have human level AI/image processing quite yet, but it would take hundreds of thousands of watts to accomplish the same thing at this time.


They have numerous problems. They are wrong a lot and die constantly as prime examples.


Containers killed the performance star.


I don't see how this could be true. Containers are just processes with some extra permissions applied.


Is “farming to blame”, or is farming being blamed to suit an agenda?

Don’t push ridiculous articles like this with zero factual evidence. What we put out to the world has real effects- especially dangerous rhetoric like this that incites the left side of the Bell curve into a frenzy.


The agenda is preventing the extinction of human life.


I’m pretty sure we need farming to continue existing as a species. Insane rhetoric like blaming cow farts on the end of the world will lead to the death of hundreds of millions due to starvation.


Cow farts are contributing to the end of the world, and that's a fact. Denying reality will lead to the death of billions due to starvation. Were you unaware there are other things you can eat besides cows? Did someone pay you to post this?


I have found the name for the AI that takes down chatGPT.

StinxNet


Not a very good source.

From the C section:

“We all study C in high school or intermediate. But, most of the aspirants or programmers struggle while coding”

“15 Tips to improve your coding skills for C”

This is borderline Engrish.

It would be nice if the people writing this used the “best practices” for the language the article is actually written in.


Yes, the C section was where I started and stopped, too.

> "Always save your files before compiling"

Okay? I guess that's a best practice?


Ditto the Python section. Very weak sauce.

Also, the idea that language-specific best practices are more important than language-agnostic ones is bonkers.


I love me some Python, trust me. But this is just putting lipstick on a pig. The language needs to be rewritten from the ground up. If you’ve ever analyzed the machine code a simple python script spits out you’ll see how helplessly bloated it is.


You can make a Python-ish language that can run fast (or at least, a lot faster) but it cannot be Python: the dynamic nature of the language means many optimizing techniques just aren't available.

The unfortunate thing is that the vast majority of Python code in use today doesn't need all those super-dynamic features. So it would run just fine on a cut-down JITed interpreter. But there's always the corner cases.

In retrospect, Python 3 was a lost opportunity here: it could have broken more compatibility, enabled multi-core and JITs, and then the 10 year transition pain would actually have been worth it. But that's hindsight, of course.


>the dynamic nature of the language means many optimizing techniques just aren't available.

This is something that seems like it should be true, but counter evidence exists that proves that it's not the case.

The first example would be V8, the JavaScript JIT compiler used in Chrome and NodeJs (and probably other things). V8 is many times faster than CPython in pretty much every situation.

The second, and even better example is SBCL, a Common Lisp compiler. SBCL is quite a bit faster than CPython and V8, it's closer to the JVM in terms of performance in benchmarks that I have saw.

The third example would be some of the Scheme compilers, like Chez and Gambit, which are not far off from SBCL.

Maybe you could argue that JavaScript is not as dynamic as Python. I don't know JavaScript at all so maybe that is the case.

I'm pretty sure that Common Lisp and Scheme are not less dynamic though. I think Common Lisp is actually more dynamic but I don't have any way to measure this, so it's just my opinion.

So assuming these languages are as or more dynamic than Python, this seems to be proof that Pythons dynamic-ness is not the reason for it's poor performance!

The Lisp compilers are also much less widely used and have much less engineering power available!

I think these counter examples are pretty interesting and don't know exactly what to make of it. Python has more funding and more users to contribute to it (except in the case of V8), I guess until now they just haven't put any of that into performance.


Python is "stupid dynamic"; it exposes implementation details which can't work work well under compilation, like accessing a caller's local variables.


Yes, but Common Lisp is also "stupid dynamic"!

I don't think there's anything Python can do that Common Lisp can't in terms of dynamic-ness!

This is a quote from python.org:

>These languages are close to Python in their dynamic semantics, but so different in their approach to syntax that a comparison becomes almost a religious argument: is Lisp's lack of syntax an advantage or a disadvantage? It should be noted that Python has introspective capabilities similar to those of Lisp, and Python programs can construct and execute program fragments on the fly. Usually, real-world properties are decisive: Common Lisp is big (in every sense), and the Scheme world is fragmented between many incompatible versions, where Python has a single, free, compact implementation.

https://www.python.org/doc/essays/comparisons/

I believe there are dynamic things Common Lisp can do that python can't, like modifying and creating classes, inheritance and methods at runtime, even with effects propagating out to already existing class instances!


Common Lisp keeps the stupid dynamic parts out of language areas that are connected to critical code execution paths. For instance, no aspect of lexical variables is dynamic. But you have dynamic variables, which are separate in such a way that a compiler can easily tell the difference.

I believe there are areas of CLOS which are stupid dynamic; but even there, the specification tries to tread carefully. Firstly, you don't have to use CLOS in a Lisp program; and if you need data structures with named slots, structs may suffice.

Importantly, Common Lisp keeps a kind of basic type versus class type separation in the language. You don't feel it because it's not obnoxious, like int versus Integer in Java. Built in basic object types like integers and strings all have a CLOS class in Common Lisp. But, the class of that class (the metaclass) is not the same as that of a class which the application defines with defclass. The Lisp compiler doesn't have to worry about silly monkey patching being perpetrated on a string or integer.

In some areas of the language, it's clear that the designers were trying to avoid bringing in dynamic behavior that would interfere with performance. For instance, conditions are defined in such a way that they are "class-like" objects, but without the actual requirement that they be CLOS instances.

The meta-object protocol (MOP) was also kept out of the language. I'm not sure whether the MOP is "stupid dynamic" because it also seems to hold the keys to avoiding "stupid dynamic" in that if you don't like some particular dynamism in a given class, maybe you can design your own meta-class which avoids it. It might be possible using MOP to, say, have an object system where the inherited slots of a derived class are at the same offset in the underlying vector storage as in the parent class, so accesses can be optimized. Maybe you can ban multiple inheritance in that meta-class.


Those are interesting points, thank you for writing all of that out!


> Yes, but Common Lisp is also "stupid dynamic"!

It's not. Common Lisp was designed to enable Lisp applications to be delivered with reasonable performance, first in 1984, when an expensive computer might have had 1 to 10 Megabytes (!) of memory and a CPU with 8 Mhz / 1 Million instructions per second. You'll then see a bunch of different implementations, sometimes within the same running Lisp and able to use different execution modes in the same program:

* source interpreted Lisp -> a Lisp Interpreter executes the code from traversing the s-expressions of the source code -> this is usually slow to execute, but there are also very convenient debug features available

* compiled Lisp code -> a Lisp compiler (often incremental) compiles Lisp code to faster code: byte code for a VM, C code for a C compiler or machine code for a CPU. -> often this keeps a lot of the dynamic features

* optimized compiled Lisp code -> like above, but the code may contain optimization hints (like type declarations or other annotations) -> the compiler uses this provided information or infers its own to create optimized code.

For "optimized compiled Lisp code" the compiler may remove all or some of dynamic features (like late binding of functions, allowing data of generic types to be passed, runtime type checks, runtime dispatch, runtime overflow detection, removal of debug information, tail call optimization, ...). It may also inline code. The portions where such optimizations are applied span from certain parts of functions to whole programs.

Common Lisp also has normal function calls and generic function calls (CLOS) -> the latter are usually a lot slower and people are experimenting with ways to make it fast (-> by removing dynamism where possible).

So, speed in Common Lisp is not one thing, but a continuum. Typically one would run compiled code, where possible, and run optimized code only where necessary (-> in parts of the code). For example one could run a user interface in unoptimized very dynamic compiled code and certain numeric routines in optimized compiled code.

  CL-USER> (defun foo (a b)
             (declare (optimize (speed 3) (safety 0))
                      (fixnum a b))
             (the fixnum (+ a (the fixnum (* b 42)))))

  CL-USER> (disassemble #'foo)
  ; disassembly for FOO
  ; Size: 28 bytes. Origin: #x70068A0918                     ; FOO
  ; 18:       5C0580D2         MOVZ TMP, #42
  ; 1C:       6B7D1C9B         MUL R1, R1, TMP
  ; 20:       4A010B8B         ADD R0, R0, R1
  ; 24:       FB031AAA         MOV CSP, CFP
  ; 28:       5A7B40A9         LDP CFP, LR, [CFP]
  ; 2C:       BF0300F1         CMP NULL, #0
  ; 30:       C0035FD6         RET
  NIL
As you can see, with optimization instructions and type hints, the code gets compiled to tight machine code (here ARM64). Without those, the compiled code looks very different, much larger, with runtime type checks and generic arithmetic.


Nothing prevents a Python dynamic compiler to follow a similar approach though, specially now that type annotations are part of the language.

And in any case, there are the Smalltalk and SELF JITs as an example of highly dynamic environments, where anything goes.


With declarations which are promises from the programmer to the compiler (I promise this is true, on penalty of undefined behavior), you can fix a lot of "stupid dynamic".

Python could have a declaration which says, "this function/module doesn't participate in anything stupidly dynamic, like access to parent locals". If it calls some code which tries to access parent locals, the behavior is undefined.

That's kind of a bad thing because in Lisp I don't have to declare anything unsafe to a compiler just to have reasonably efficient local variables that can be optimized away and all that.


Type annotations are defined to be completely ignored by the interpreter.

So, as of today, they’re useless for optimization. That could be changed, but hasn’t been so far.


I'm not exactly sure how anything you said supports that CL isn't a dynamic language.

When using SBCL for example, none of CLs dynamic features are restricted from the programmer in any way. So whether it's compiled to native code or not has no bearing at all on how dynamic the language is.

Can you explain to me why a Python compiler couldn't implement optimizations similar to SBCL?

>It's not.

Is Python more powerful than CL in some way that I am not aware of?


I tried to explain that the optimized version of Common Lisp is less dynamic than the non-optimized version. The speed advantage often comes because the compile code is less or not dynamic. Late binding for example makes code slower because of another indirection. An optimizing compiler can remove late binding. The code will be faster, but there might no longer be a runtime lookup of the function anymore.

> When using SBCL for example, none of CLs dynamic features are restricted from the programmer in any way.

Sure, but it will be slower in benchmarks. The excellent benchmark numbers of SBCL is in part a result of being able to cleverly remove dynamic features.


Just like Smalltalk and SELF, which expose everything and can change the whole image at any execution step.


Besides the sibling comment, Smalltalk and SELF JITs prove otherwise.

Ongoing Ruby efforts as well.


And yet, after 30 years of effort from various different, talented people and teams, with historical knowledge of eg, StrongTalk, and Self, and Common Lisp, and Java, and JavaScript, we've yet to see any major leaps in Python performance.

So, in my opinion, it's clearly not as simple as just taking all of that existing knowledge and a good team and just doing it, or one of the many efforts to do so would almost certainly have succeeded by now.


Do you have thoughts around the concept of Python becoming a Rust macro based language? I read another comment about that being a potential future for Python but I don't know how feasible it is.

I've moved on to Go for things where I need to care about performance but like thinking about things in a similar way Python lets me think about them.


> If you’ve ever analyzed the machine code a simple python script spits out you’ll see how helplessly bloated it is.

How would one do that? I thought python generated bytecode and interpreted that code? Where's the machine code? Do you mean dissembling the python interpreter itself? In which case it would be gcc/llvm spitting out machine code, no?


I prefer C without braces


C is still the King of languages.


I agree with that

None of the new languages managed to capture what makes C great

The few "modern" ones are interesting, Zig, Jai and Odin for example, I like how they took C designated initialization to the next level

Zig's comptime is also nice

D is nice, but is loosing its charm now that the competition is here.. also what used to be a D strength now is a weakness; it's slow to compile thanks to the std.. debugging still is a pain, and code can become quite overly verbose


Almost, it is the prince of memory corruption bugs, the throne belongs to Assembly.


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

Search: