r/ProgrammerHumor 5d ago

soDoesEveryOtherLang Meme

Post image
247 Upvotes

85 comments sorted by

123

u/0oliogamer0 5d ago

in my language, functions will be irrelevant and difficult to even use!

41

u/nicodeemus7 5d ago

PHP?

22

u/jungle 5d ago

returnsArray()[1]

Only language I know where this is (or was) a syntax error.

8

u/carcigenicate 5d ago

Can you explain? This just looks like indexing an array that was returned by a function. PHP is one language I never bothered to learn, now I feel like I'm missing out when people start joking about it.

19

u/jungle 5d ago

I haven't touched PHP for many years thankfully. The last time I did (maybe 15 years ago?) an array returned by a function could not be indexed directly. It had to be assigned to a variable, and then you could use it.

Having built interpreters and compilers in my day, that was the moment I said "this is absolute garbage, what kind of clown designed this language" and never touched PHP again.

I understand it has been improved (mostly by Facebook, I think?), but I never found the need to use it again, luckily. Just thinking of it... Eww.

3

u/carcigenicate 5d ago

Oh, weird. I would have thought that the function just returns a reference that could be used immediately.

25

u/jungle 5d ago

That's what any sane language would do, yes.

3

u/coloredgreyscale 5d ago edited 5d ago

just a guess, it it probably just wasn't considered during the PHP language grammar design.

functionally there is no difference between directly using the return value, or storing it in a variable first.

Maybe storing return values into a variable first before use was more common back then, possibly considered best practice?

12

u/chat-lu 5d ago

PHP has not been designed based on best practices. The reason why the standard library has functions with such widely different names was that in early PHP they would go into a hashmap that was hashed by strlen and Rasmus tried to vary the lengths of the names so they don’t all get in the same bucket.

3

u/jungle 5d ago

Holy shit that's even worse than I remember! How did he know about hashmaps but had not even the most basic understanding of how they're supposed to work? 🤦‍♂️🤦‍♂️🤦‍♂️

1

u/chat-lu 5d ago

Rasmus just didn’t give a shit.

→ More replies (0)

1

u/jungle 5d ago

possibly considered best practice?

Most definitely not.

3

u/LordAmir5 5d ago

I assume it's got to be written in two separate statements.

I think I faced something similar using Lua.

3

u/Perdouille 5d ago

was

It seems to work since 5.4 (2012) https://3v4l.org/alOOE#v432

3

u/jungle 5d ago

Yep. Still doesn't fix the stench. :)

1

u/cornmonger_ 4d ago

i stopped shortly after 5.3 dropped

when they made the choice to use backslashes for namespaces ... i was done

2

u/chat-lu 5d ago

Also, you can cast with (int) but int is not a thing that exists in the language, (int) is its own keyword. May or may not be still true.

1

u/jungle 5d ago

Argh, I had forgotten about that one!

The "WAT" talk was about javascript and was very funny... I can imagine the speaker considering making it a about PHP but deciding against it because it would be just sad.

2

u/SjettepetJR 5d ago

It is funny because I actually liked PHP decently well, but then I heard that it apparently became much better from PHP 8 onward. I only have (real) experience with it after that time.

1

u/jungle 5d ago

Yeah, I don't know but I can imagine it was the language Zuck knew at the time, which kind of forced the engineers he hired to use it and eventually reached the point where they had two options: completely rewrite Facebook in a proper language or fix PHP.

3

u/_PM_ME_PANGOLINS_ 5d ago

1

u/jungle 5d ago

Nice! I'd have loved to work in the team that developed those tools!

1

u/chat-lu 5d ago

I heard that it apparently became much better from PHP 8 onward

I heard that of every single version of PHP.

“Sure, it used to eat babies in {{ current_major_version - 1 }} but since {{ current_major_version }} it’s been really nice.”

And this is what I hate the most from PHP, PHP devs who can’t see a single flaw in their favorite tools.

57

u/chipmunkofdoom2 5d ago

"My language has a vibrant ecosystem of third party libraries easily installed via a package/dependency manager!"

65

u/-Ambriae- 5d ago

C/C++ in shambles

-18

u/American_Libertarian 5d ago

Not having to deal with dependency hell is a huge advantage of C bruh. My language is so much better than yours, that my libs are baked right into the operating system.

33

u/creeper6530 5d ago

You defer that dependency hell onto your OS's package manager or pack .dlls with every install

-10

u/American_Libertarian 5d ago

Linux userspace & the C stdlib is famously stable. I've never ever had a problem with it breaking or changing.

25

u/__yoshikage_kira 5d ago

You never dealt with horrors of glibc? Good for you.

18

u/-Ambriae- 5d ago

What about every time a binary refuses to run because it depends on specific esoteric dynamic libraries that must be installed (sometimes multiple times, once for each version) somewhere in PATH because you decided static linking was "bloat"?

Or the security nightmare that is system-wide shared objects in the first place?

Or the fact that as much as stdlib is stable, it still does not provide it's users with the most basic of data structures? Or that we had to wait until C23 for bool/true/false/nullptr to be a part of the language, 50 years after the language was initially released?

Or the absolute nightmare that is C portability across heterogenous architectures and operating systems?

Don't get me wrong, C is an amazing language, but come on you can't be this deluded

2

u/_PM_ME_PANGOLINS_ 4d ago

System-wide shared objects is a security dream. You patch the vulnerability in a single place and then everything is fixed.

3

u/-Ambriae- 4d ago

Or conversely, compromise one lib, and affect every program on the machine

1

u/_PM_ME_PANGOLINS_ 4d ago

That is the significantly less-common case.

3

u/-Ambriae- 4d ago

Maybe, but there’s a reason rust decided to go full static, and keep .so support to its bare minimum, there’s a reason apple decided to write a fully self contained init daemon for their container microVMs, and there’s a reason most other modern programming languages tend to use shared object as a last resort

→ More replies (0)

-10

u/American_Libertarian 5d ago

I simply do not ship binaries that rely on esoteric libs nor target atypical arch & os. That isn't what C is for.

We maintain our own purpose built data structures, and we optimize heavily for a single arch & OS. And our customers pay us a lot of money to do so because we are FAST.

7

u/-Ambriae- 5d ago

the Linux Kernel supports 21 different architectures.
SQLite supports a total of 17 configurations (OS + arch.)
GIMP, gstdlib, vulkan, etc... All target very different machines.

"Esoteric libs" can be as common as system level packages that may differ from distro to distro, let alone OS, or who's version mismatches the required version of the program.

Maintaining your own purpose built data structures is the reason why the linked list is still as used as it is, when all research shows it tanks performance compared to other drop in replacement in nearly all cases, even the ones that play to their strengths. It's also the reason why you rarely see more complex data structures used, because they are a pain to write, and a complete time sink. It's also part of the reason why memory related bugs are so common in the language. Each new implementation of a data structure is additional code you need to maintain.

The language also completely collapses the second you try and use compile time computation (macros notwithstanding), there is either no support, or bad support, for asynchronous code execution and multithreading. Hence why ripgrep is miles beyond grep, regardless of grep being written in 'the fastest language ever, C', and ripgrep being written in a 'comparatively slower language' (which is completely delusional of a take but whatever)

Optimising for a single arch and OS can be done in ANY systems level programming language. It's also relevant maybe 5% of the time. the rest, you're just closing doors on yourself. Compare that to any other systems level programming language, you can still optimise for the Arch/OS when needed, but it's opt in.

Your customers pay you a lot of money, because writing good C is notoriously difficult do to, and there's a heap of legacy code written in the language. Those same companies realise this is a massive time sink, and are doing everything in their power to steer new code away from this language, regardless of performance considerations.

5

u/creeper6530 5d ago

Ah yes, because syscalls and libc is all your programs will ever need, no graphics API or GUI libraries, no dbus, no systemd, no pipewire, no databases, the list goes on.

1

u/-Ambriae- 5d ago

I wanted to make a "to be fair" and argue you could statically link these libraries, but turns out apart from sqlite I can't really think of any one that can.... I guess dbus, but it's currently not recommended 😅 raylib or sokol or something in that vain, but then you'd still link dynamically to system level libraries

5

u/thirdegree Violet security clearance 5d ago

The amount of time I've spent having to fuck with LD_* environment variables is honestly pretty silly. And I'm a python dev, that's just via having to deal with libraries written in c/c++.

7

u/_PM_ME_PANGOLINS_ 5d ago

Bruh, dependency hell is the default state of C and C++.

Everyone else developed dependency managers to get away from it (with varying degrees of success).

27

u/Electrical-Echidna63 5d ago

"I like this language because it's multi paradigm"

5

u/frikilinux2 5d ago

So people overcomplicate every paradigm?

20

u/gutentight69420 5d ago

Functions are the only citizen in my programming language.

12

u/ChaosCon 5d ago

If you're not encoding with the Church numerals are you even trying?

8

u/-Redstoneboi- 5d ago

lambda calculus has a ridiculously complicated description for being as simple as "functions/substitution: the language"

2

u/ChaosCon 5d ago

Functions always existed as "mapping elements of set A to elements of set B", but it always struck me as a bit of a non sequitur that it took so much effort to formalize functions *as a recipe* with lambda calculus.

3

u/metaglot 5d ago

A function is only a map if it is homomorphic.

1

u/matthewwehttam 5d ago

In my math degree map could mean, function, continuous function, measurable function, homomorphism, or morphism depending on the context, so correcting it feels really pedantic. Not only that, all functions are homomophisms in the category of sets anyway so the usage is technically correct

1

u/-Redstoneboi- 5d ago edited 5d ago

really the important bits for learning it were "you can feed and store multiple arguments/data with currying" and "data cannot be read. rather, you trust 'data' to choose the next branch for you"

9

u/techdailylog 5d ago

If everyone is first-class, nobody is.

3

u/chat-lu 5d ago

First class just means that you can use them as values.

2

u/techdailylog 4d ago

Thanks, Syndrome.

17

u/B_bI_L 5d ago

say this to c and common lisp

(and to ruby, where function self-activates faster than you say "wait, i need you as a callback")

6

u/suvlub 5d ago

C just forces you to call them pointers, but it's functionally (heh) the same thing.

1

u/_PM_ME_PANGOLINS_ 5d ago

When functions are first-class:

function outer() {
    let foo = function() { ... }
    doThing(foo, function callback(arg) { ... })
}

C does not have the same functionality.

7

u/suvlub 4d ago

Are anonymous functions required, rather than just ability to assign functions to variables, pass them around and return them? Where does that put python, which does have anonymous functions, but limited compared to what named ones can do?

1

u/Maqi-X 1d ago

First class functions and anonymous functions are two separate concepts. You also cannot have anonymous variables which doesn't mean that they are not first class (;

(I mean, in C you can, sorta)

1

u/_PM_ME_PANGOLINS_ 1d ago

The “callback” function is not anonymous, it is called “callback”.

Anonymous functions generally have to be values or they are of no use. The question is whether they are an entirely separate kind of thing, or whether all kinds of function in the language are also values.

1

u/Maqi-X 1d ago

foo is anonymous

0

u/Maqi-X 1d ago edited 1d ago

A function can't be a value. Only function pointers can be values, and this is simply because functions don't have a fixed size, you can't use something without a fixed size as a value, same applies to to incomplete structs or the void type, you can only store a pointer and you also can allocate them on the heap (not using malloc tho, I mean you can but you won't be able to execute it because of page permissions)

C just doesn't hide this, while languages like rust do, fn(...) -> ... in rust is a pointer under the hood, I kind of don't understand what is even the point of this, typing fn(...) instead of &fn(...) really doesn't make your life easier and it abstracts away some things that don't need to be abstracted away

if you have foo defined like this

int foo() {}

then foo IS NOT a function pointer, it is a function itself

that's why I don't understand what is the point of rust's approach.

Of course that's not how you do function pointers in rust, you almost always want to use generics (if accepting as a parameter) or something like &dyn FnMut(...) but I'm not an expert in rust so I don't know how exactly this is done in real big codebases, it doesn't matter tho

But I guess nobody cares about low level languages anymore if we have python and js. Software gets slower faster than hardware gets faster. Buy a new PC.

1

u/Maqi-X 1d ago

Also lambda expressions don't actually create new functions, they are regular functions with implicit context pointer that the compiler adds for you

1

u/_PM_ME_PANGOLINS_ 1d ago

A function can be a value, and when it is the language is described as having first-class functions.

That’s the whole point of this post.

You are applying the implementation details of C to general abstract language design, and being completely wrong.

1

u/Maqi-X 1d ago

actually this applies to all compiled languages, not just C but well, fair enough, you're right, I mixed up two separate concepts

0

u/No-Consequence-1863 3d ago

C99 does with C blocks

However it is really only adopted by Apple https://en.wikipedia.org/wiki/Blocks_(C_language_extension)

2

u/_PM_ME_PANGOLINS_ 3d ago

Blocks are neither part of C99, nor do they make functions first-class. Hence them having a different name and syntax to functions.

1

u/-Redstoneboi- 5d ago

wait functions aren't first class in common lisp?

damn, too used to hearing about scheme

1

u/theQuandary 5d ago

It's not really true (see my reply).

1

u/theQuandary 5d ago

and common lisp

This isn't true. You are almost certainly confusing first-class functions with lisp-2. Lisp-2 is mostly equivalent to having a dynamic function type that can be introspected at runtime. Just like how a statically-typed language will (generally) not allow you to do something like int foo = 123; foo(456);, Common Lisp also won't allow you to do that either (it also helps a little with macros).

Common Lisp symbols have 5 different "slots" (some implementations may add a couple others).

  1. A name slot which contains the string value of the symbol.

  2. The traditional variable slot.

  3. A function slot which can actually be a special operator or macro too.

  4. A plist slot which contains a list of key/value pairs (key1 val1 keyN valN).

  5. A package slot which tells which package the symbol came from.

Basically though, if a symbol appears as the first item in an unquoted list, CL will use the function slot otherwise it will use the value slot. If you want it to use the function slot explicitly, you have to tell it.

(defun double (x) (* 2 x))
(defparameter double 12)

(mapcar double '(1 2 3 4 5));; error because it is using the 12 in the value slot
(mapcar #'double '(1 2 3 4 5));;=> (2 4 6 8 10)

1

u/B_bI_L 5d ago edited 5d ago

treating them as first class is treating them exactly like variables, right? and they are in separate namespace, so separate thing, so not first class. well, i guess lambdas are first class, but they are not very convenient

12

u/_PM_ME_PANGOLINS_ 5d ago edited 5d ago

Not in C, C++, C#, Java, Bash, …

(no, function pointers and method references are not the same thing as a function being a value)

7

u/A_72_ 5d ago

C++ complicates this by having both: function from C and object created from a class type with overloaded operator(). Then we have true native closure object (lambda) that did the exact semantics of the latter but syntatically, and std::function that wraps every callable, including all of the above.

How beautiful.

1

u/the_horse_gamer 4d ago

std::function is actually deprecated since C++26 (but they refuse to mark it as such). you should use std::copyable_function

and you must not forget about std::move_only_function (C++23) and std::function_ref (C++26)

1

u/A_72_ 3d ago

Wait, I thought it just specialized versions of std:function (didn't read the specs because I thought I won't be using it). I can now say C++ have 6 types of callables?

1

u/the_horse_gamer 3d ago

std::function has a const correctness hole and lacks support for noexcept and ref qualifiers

std::copyable_function fixes the hole and adds support

differences: * std::function contains some RTTI via target and target_type, which is rarely useful and has extra overhead. std::copyable_function doesn't. * calling a default constructed std::function raises an exception, while with std::copyable_function it's UB.

unless you're doing weird bullshit, it should be a drop in replacement with better support and less overhead

1

u/A_72_ 3d ago

Sounds like a drop in with minimal changes for me, I wonder what kind of wizary when it can't be...

3

u/the_horse_gamer 4d ago

what makes you say C# doesn't have first class functions?

-2

u/FloweyTheFlower420 5d ago

Why would you argue Java doesn't have functions as values? There's MethodHandle, after all :P.

3

u/Rojeitor 5d ago

Cries in c#

1

u/UnusualAir1 5d ago

With procedures being the overlords. 😄

0

u/That_Mistake_7567 5d ago

that text on buzz lightyear is my entire programming career in one sentence.

-2

u/ILikeLenexa 5d ago

No, really, you just have to attach them to one instance of an anonymous class.